Windows 批处理:如何使用 for /f 循环保留空行
Windows Batch: How to keep empty lines with loop for /f
我正在寻找如何在使用 for 循环浏览文件时保留空行。
for /f "tokens=1* delims=[" %%i in ('type "test1.txt" ^| find /v /n ""') do (
SET tmp=%%i
echo !tmp! >> test2.txt
)
实际上它对每个人都有效,但就我而言它不起作用。
例如,如果 test1.txt 内容是:
Hello I come from France
I live in Paris
I'm sorry I don't know English, could we speak French please?
If it doesn't bother you
Thank you
test2.txt 中的结果将是:
[1
[2
[3
[4
[5
[6
[7
如果我把星号“*”附近的“1”去掉,结果是:
[1]Hello I come from France
[2]I live in Paris
[3]
[4]I'm sorry I don't know English, could we speak French please?
[5]If it doesn't bother you
[6]
[7]Thank you
期望的输出是:
Hello I come from France
I live in Paris
I'm sorry I don't know English, could we speak French please?
If it doesn't bother you
Thank you
你能帮我解决这个问题吗?
这可以像
那样完成
@echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,* delims=]" %%a in ('
find /n /v "" ^< "file1.txt"
') do (
>> "file2.txt" echo(%%b
)
内部 find
命令的输出类似于
[123]texttexttext
代码使用右括号作为分隔符,因此标记(我们请求两个标记:1,*
或 1*
)是
[123 texttexttext
^ ^
1 2
%%a %%b
但是,由于重复的分隔符仅作为一个分隔符处理,如果一行以右括号开头,它将被删除。这是可以预防的
作为
@echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,* delims=0123456789" %%a in ('
find /n /v "" ^< "file1.txt"
') do (
set "line=%%b"
setlocal enabledelayedexpansion
>>"file2.txt" echo(!line:~1!
endlocal
)
此处数字用作分隔符,行标记为
[ ]texttexttext
^ ^
%%a %%b
然后将第二个标记的值存储在一个变量中,禁用延迟扩展以避免数据内部出现感叹号问题(即 handled/replaced解析器(如果延迟扩展处于活动状态)
一旦数据在变量中,延迟扩展被激活(我们想要从代码块中更改的变量中检索内容时需要的东西)从第二个位置(字符串中的第一个字符)输出行为 0) 以删除右括号。一旦完成,延迟扩展将再次被禁用。
edited 由于 OP 必须将其合并到 larger/complex 脚本中,此代码应该面临最常见的问题
@echo off
rem For this test we will have delayed expansion from the start
setlocal enableextensions enabledelayedexpansion
rem External code block that will make delayed expansion necessary
if 1==1 (
rem Variables changed inside block
set "input_file=file1.txt"
set "output_file=file2.txt"
rem Grab a reference to the content of the file variables
for %%i in ("!input_file!") do for %%o in ("!output_file!") do (
rem Prepare the environment for file work
setlocal disabledelayedexpansion
rem Prepare output file
type nul > "%%~fo"
rem Process input file and write to output file
for /f "tokens=1,* delims=0123456789" %%a in ('
find /n /v "" ^< "%%~fi"
') do (
set "line=%%b"
setlocal enabledelayedexpansion
>>"%%~fo" echo(!line:~1!
endlocal
)
rem Restore the previous environment
endlocal
)
)
这是一个略有不同的变体,使用 findstr
command rather than find
and doing the redirection 到输出文件 file2.txt
仅一次,而不是每个 for /F
循环迭代:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
>> "file2.txt" (
for /F "delims=" %%a in ('findstr /N "^" "file1.txt"') do (
set "line=%%a"
setlocal EnableDelayedExpansion
echo(!line:*:=!
endlocal
)
)
endlocal
findstr
命令在每行前面加上行号和冒号,如下所示:
1:Hello I come from France
sub-string substitution 部分 !line:*:=!
将第一个冒号之前的所有内容(由于 *
)替换为空,因此删除了这个。
将 >>
运算符替换为 >
,以防您想覆盖现有文件而不是附加到它。
将您的循环命令发送到 con:
设备:
- 在命令行中:
for /F tokens^=^* %F in ('type File.txt <b>^>con:</b>')do @echo/%F
- 在你的 bat 文件中:
for /F tokens^=^* %%F in ('type File.txt <b>^>con:</b>')do echo;%%F</pre>
我正在寻找如何在使用 for 循环浏览文件时保留空行。
for /f "tokens=1* delims=[" %%i in ('type "test1.txt" ^| find /v /n ""') do (
SET tmp=%%i
echo !tmp! >> test2.txt
)
实际上它对每个人都有效,但就我而言它不起作用。 例如,如果 test1.txt 内容是:
Hello I come from France
I live in Paris
I'm sorry I don't know English, could we speak French please?
If it doesn't bother you
Thank you
test2.txt 中的结果将是:
[1
[2
[3
[4
[5
[6
[7
如果我把星号“*”附近的“1”去掉,结果是:
[1]Hello I come from France
[2]I live in Paris
[3]
[4]I'm sorry I don't know English, could we speak French please?
[5]If it doesn't bother you
[6]
[7]Thank you
期望的输出是:
Hello I come from France
I live in Paris
I'm sorry I don't know English, could we speak French please?
If it doesn't bother you
Thank you
你能帮我解决这个问题吗?
这可以像
那样完成@echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,* delims=]" %%a in ('
find /n /v "" ^< "file1.txt"
') do (
>> "file2.txt" echo(%%b
)
内部 find
命令的输出类似于
[123]texttexttext
代码使用右括号作为分隔符,因此标记(我们请求两个标记:1,*
或 1*
)是
[123 texttexttext
^ ^
1 2
%%a %%b
但是,由于重复的分隔符仅作为一个分隔符处理,如果一行以右括号开头,它将被删除。这是可以预防的 作为
@echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,* delims=0123456789" %%a in ('
find /n /v "" ^< "file1.txt"
') do (
set "line=%%b"
setlocal enabledelayedexpansion
>>"file2.txt" echo(!line:~1!
endlocal
)
此处数字用作分隔符,行标记为
[ ]texttexttext
^ ^
%%a %%b
然后将第二个标记的值存储在一个变量中,禁用延迟扩展以避免数据内部出现感叹号问题(即 handled/replaced解析器(如果延迟扩展处于活动状态)
一旦数据在变量中,延迟扩展被激活(我们想要从代码块中更改的变量中检索内容时需要的东西)从第二个位置(字符串中的第一个字符)输出行为 0) 以删除右括号。一旦完成,延迟扩展将再次被禁用。
edited 由于 OP 必须将其合并到 larger/complex 脚本中,此代码应该面临最常见的问题
@echo off
rem For this test we will have delayed expansion from the start
setlocal enableextensions enabledelayedexpansion
rem External code block that will make delayed expansion necessary
if 1==1 (
rem Variables changed inside block
set "input_file=file1.txt"
set "output_file=file2.txt"
rem Grab a reference to the content of the file variables
for %%i in ("!input_file!") do for %%o in ("!output_file!") do (
rem Prepare the environment for file work
setlocal disabledelayedexpansion
rem Prepare output file
type nul > "%%~fo"
rem Process input file and write to output file
for /f "tokens=1,* delims=0123456789" %%a in ('
find /n /v "" ^< "%%~fi"
') do (
set "line=%%b"
setlocal enabledelayedexpansion
>>"%%~fo" echo(!line:~1!
endlocal
)
rem Restore the previous environment
endlocal
)
)
这是一个略有不同的变体,使用 findstr
command rather than find
and doing the redirection 到输出文件 file2.txt
仅一次,而不是每个 for /F
循环迭代:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
>> "file2.txt" (
for /F "delims=" %%a in ('findstr /N "^" "file1.txt"') do (
set "line=%%a"
setlocal EnableDelayedExpansion
echo(!line:*:=!
endlocal
)
)
endlocal
findstr
命令在每行前面加上行号和冒号,如下所示:
1:Hello I come from France
sub-string substitution 部分 !line:*:=!
将第一个冒号之前的所有内容(由于 *
)替换为空,因此删除了这个。
将 >>
运算符替换为 >
,以防您想覆盖现有文件而不是附加到它。
将您的循环命令发送到 con:
设备:
- 在命令行中:
for /F tokens^=^* %F in ('type File.txt <b>^>con:</b>')do @echo/%F
- 在你的 bat 文件中:
for /F tokens^=^* %%F in ('type File.txt <b>^>con:</b>')do echo;%%F</pre>