Windows Batch:如何为/ f保留带有循环的空行

Rom*_*om1 4 batch-file delimiter blank-line

当我用for循环浏览文件时,我正在搜索如何保持空行.

for /f "tokens=1* delims=[" %%i in ('type "test1.txt" ^| find /v /n ""') do (
SET tmp=%%i
echo !tmp! >> test2.txt
)
Run Code Online (Sandbox Code Playgroud)

实际上它适用于所有人,但就我而言,它不起作用.例如,如果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
Run Code Online (Sandbox Code Playgroud)

test2.txt中的结果将是:

[1 
[2 
[3 
[4 
[5 
[6 
[7 
Run Code Online (Sandbox Code Playgroud)

如果我在"*"附近放下"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 
Run Code Online (Sandbox Code Playgroud)

期望的输出是:

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
Run Code Online (Sandbox Code Playgroud)

能帮我解决一下这个麻烦吗?

非常感谢你.

MC *_* ND 7

这可以做到

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "tokens=1,* delims=]" %%a in ('
        find /n /v "" ^< "file1.txt"
    ') do (
        >> "file2.txt" echo(%%b
    )
Run Code Online (Sandbox Code Playgroud)

内部find命令的输出就像

[123]texttexttext
Run Code Online (Sandbox Code Playgroud)

代码使用右括号作为分隔符,因此令牌(我们请求两个令牌:1,*1*)是

[123 texttexttext
^    ^
1    2
%%a  %%b
Run Code Online (Sandbox Code Playgroud)

但是,由于重复的分隔符只作为一个分隔符处理,如果一行以一个右括号开头,它将被删除.这可以作为

@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
    )
Run Code Online (Sandbox Code Playgroud)

这里的数字用作分隔符,行标记为

[   ]texttexttext
^   ^
%%a %%b
Run Code Online (Sandbox Code Playgroud)

然后第二个令牌的值存储在一个变量中,禁用延迟扩展以避免数据内部的惊叫问题(如果延迟扩展处于活动状态,将由解析器处理/替换)

一旦数据在变量内部,就会激活延迟扩展(因为我们想要从代码块中更改的变量中检索内容所需的内容)从第二个位置输出行(字符串中的第一个字符为0)以删除结束括号.完成后,再次禁用延迟扩展.

编辑的作为OP具有将它合并到更大的/复杂的脚本,此代码应面临的最常见的问题

@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
        )
    )
Run Code Online (Sandbox Code Playgroud)

  • @Cainzer,只有在进入`for/f`循环之前启用了延迟扩展时才会发生这种情况.这就是发布代码中`setlocal enableextensions disabledelayedexpansion`的原因.如答案所示*延迟扩展*需要禁用. (3认同)