windows 在批处理文件中嵌套 for 循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3137997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nesting for loop in batch file
提问by user375191
I want to nest a for loop inside a batch file to delete carriage return. I tried it like you can see below but it does not work.
我想在批处理文件中嵌套一个 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
Here I want to check with windows.cpp. If its working I like to change windows .cpp with !v%%i!
在这里,我想检查 windows.cpp。如果它可以工作,我喜欢用 !v%%i! 更改 windows .cpp!
回答by Joey
You cannot do this in a batch file. You have no way of addressing or writing arbitrary characters. Every tool on Windows normally makes sure to output Windows line breaks (i.e. CR+LF). Some can readUnix-style line breaks just fine, which is why you can easily convert fromthem. But tothem isn't possible.
您不能在批处理文件中执行此操作。您无法寻址或写入任意字符。Windows 上的每个工具通常都会确保输出 Windows 换行符(即 CR+LF)。有些人可以很好地读取Unix 样式的换行符,这就是为什么您可以轻松地从它们转换。但对他们来说是不可能的。
Also as a word of caution: Source code files often contain blank lines (at least mine do) that are for readability. for /f
skips empty lines which is why you're mangling the files for your human readers there. Please don't do that.
还要提醒一句:源代码文件通常包含空白行(至少我是这样做的),以提高可读性。for /f
跳过空行,这就是您在那里为人类读者修改文件的原因。请不要那样做。
As for your question: When nesting two loops you have to make sure that they don't use the same loop variable. Show me a language where code like you wrote actually works.
至于您的问题:嵌套两个循环时,您必须确保它们不使用相同的循环变量。向我展示一种语言,您编写的代码实际上可以在其中运行。
Something like
就像是
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
)
)
should probably work better (you missed the final closing parenthesis as well). Thing to remember: If you want to use a certain variable instead of a fixed file name it surely helps replacing that fixed file name by that variable.
应该会更好(你也错过了最后的右括号)。要记住的事情:如果您想使用某个变量而不是固定文件名,它肯定有助于用该变量替换该固定文件名。
回答by Joey
It would be probably easiest to use some unix2dos/dos2unixconverter to do that or some win32 flavor of sed.
使用一些unix2dos/dos2unix转换器或一些 win32 风格的 sed可能是最简单的。
回答by aschipfl
The intrinsic issue of your code is already addressed by another answer, hence I am going to focus on the main task you are trying to accomplish, namely converting DOS/Windows-style end-of-line markers (or line-breaks) to Unix-style ones.
您的代码的内在问题已经由另一个答案解决,因此我将专注于您要完成的主要任务,即将 DOS/Windows 样式的行尾标记(或换行符)转换为 Unix -风格的。
Doing this is very tricky in a batch file, but give the following script a try. Supposing it is called convert.bat
, and the original text file is named convert.txt
, run the script using the following command line:
在批处理文件中执行此操作非常棘手,但请尝试使用以下脚本。假设它名为convert.bat
,并且原始文本文件名为convert.txt
,请使用以下命令行运行脚本:
convert.bat "convert.txt" LF
The name of the returned file will get the original file name with _converted_EOL
appended. The second argument LF
specifies Unix-style line-breaks; omitting it will return DOS/Windows-style ones.
返回的文件名将_converted_EOL
附加原始文件名。第二个参数LF
指定 Unix 风格的换行符;省略它将返回 DOS/Windows 风格的。
So here is the code:
所以这里是代码:
@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
The following restrictions apply:
以下限制适用:
- no line must be longer than about 8190 characters (this is a general limitation of batch files);
- the file must not contain any null-bytes (well, a normal text file should not hold such, but Unicode-encoded do);
- the last line of the returned file will always be terminated by a line-break, even if the respective original line is not;
- 任何行的长度不得超过 8190 个字符(这是批处理文件的一般限制);
- 该文件不能包含任何空字节(好吧,普通的文本文件不应该包含这样的内容,但是 Unicode 编码的可以);
- 返回文件的最后一行将始终以换行符终止,即使相应的原始行不是;
And here is another solution for line-break conversions: Convert all CR to CRLF in text file using CMD
这是换行转换的另一种解决方案:Convert all CR to CRLF in text file using CMD