在批处理文件中嵌套循环

时间:2010-06-29 05:04:39

标签: batch-file batch-processing

我想在批处理文件中嵌套for循环以删除回车符。 我尝试过它就像你可以看到下面但它不起作用。

@echo off
setLocal EnableDelayedExpansion

for /f "tokens=* delims= " %%a in (Listfile.txt) do (
    set /a N+=1
    set v!N!=%%a
)

for /l %%i in (1, 1, %N%) do (
    echo !v%%i!
    for /r "tokens=* delims=" %%i in (windows.cpp) do (
        echo %%i >> Linux11.cpp
    )
)
pause

这里我想查看一下windows.cpp。如果它的工作我喜欢改变windows .cpp与!v %% i!

3 个答案:

答案 0 :(得分:7)

您无法在批处理文件中执行此操作。您无法寻址或写入任意字符。 Windows上的每个工具通常都会确保输出Windows换行符(即CR + LF)。有些人可以读取 Unix风格的换行符,这就是为什么你可以轻松地从转换它们的原因。但是它们是不可能的。

另外需要注意的是:源代码文件通常包含空白行(至少是我的),以提高可读性。 for /f跳过空行,这就是为什么你要为那里的人类读者修改文件的原因。请不要这样做。

至于你的问题:当嵌套两个循环时,你必须确保它们不使用相同的循环变量。给我看一个像你写的代码实际工作的语言。

这样的东西
for /l %%i in (1, 1, %N%) do ( 
  echo !v%%i! 
  for /f "tokens=* delims=" %%l in ("!v%%i!") do (   
    rem do whatever you want to do with the lines      )
)

应该可以更好地工作(你也错过了最后的右括号)。要记住:如果你想使用某个变量而不是固定的文件名,它肯定有助于用该变量替换那个固定的文件名。

答案 1 :(得分:1)

最简单的方法是使用一些unix2dos/dos2unix转换器来实现这一点或某些win32风格的sed。

答案 2 :(得分:0)

another answer已解决了代码的内在问题,因此,我将重点介绍您要完成的主要任务,即转换DOS / Windows样式的行尾标记(或换行符)到Unix样式的换行符。

在批处理文件中执行此操作非常棘手,但是请尝试以下脚本。假设它名为convert.bat,并且原始文本文件名为convert.txt,请使用以下命令行运行脚本:

convert.bat "convert.txt" LF

返回的文件名将获得原始文件名,并附加_converted_EOL。第二个参数LF指定Unix风格的换行符;省略它将返回DOS / Windows风格的。

下面是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem check whether or not an existing file is given as the first argument
>&2 (
    if "%~1"=="" (
        echo No file specified.
        exit /B 2
    ) else if not exist "%~1" (
        echo File "%~1" not found.
        exit /B 1
    )
)

rem get carriage-return character
for /F %%A in ('copy /Z "%~0" nul') do set "CR=%%A"

rem get line-feed character (the two empty lines afterwards are mandatory!)
(set ^"LF=^
%= blank line =%
^")

rem check which line-break is given by the second argument
rem (`CR` - carriage return (Mac); `LF` - line feed (Unix);
rem  anything else or nothing - CR+LF (Windows, default))
setlocal EnableDelayedexpansion
set "BR=!CR!!LF!"
if /I "%~2"=="CR" set "BR=!CR!" & (>&2 echo CR not supported.) & exit /B 3
if /I "%~2"=="LF" set "BR=!LF!"

rem convert line-breaks; append `_converted_EOL` to file name
setlocal DisableDelayedExpansion
> "%~n1_converted_EOL%~x1" (
    for /F delims^=^ eol^= %%L in ('
        findstr /N /R "^" "%~1"
    ') do (
        set "LINE=%%L"
        rem firstly, precede every line with a dummy character (`:`) and
        rem append the specified line-break in order to avoid the loss of
        rem leading white-spaces or trouble with leading equal-to signs,
        rem all caused by `set /P`, which is needed here to return the
        rem line without a trailing DOS/Windows-style line-break (opposed
        rem to `echo`); then, let `pause` strip off that character;
        rem lastly, let `findstr` return the remainder;
        rem (the `rem` suffix is just there to fix syntax highlighting)
        cmd /V /C ^< nul set /P #="!LINE:*:=:!!BR!" | (> nul pause & findstr "^") & rem/ "^"
    )
)
endlocal
endlocal

endlocal
exit /B

以下限制适用:

  • 任何行都不能超过8190个字符(这是批处理文件的一般限制);
  • 文件中不得包含任何空字节(嗯,普通的文本文件不应包含空字节,而应使用Unicode编码);
  • 返回的文件的最后一行将始终以换行符终止,即使相应的原始行不在此行

这是换行符转换的另一种解决方案:Convert all CR to CRLF in text file using CMD