我已经构建了一组代码,我希望它能实现以下目标:
我的输入(%tlst%)文件很简单,包含5个文件名列表,每个记录都驻留在自己的行上:
tran.txt1
tran.txt2
tran.txt3
tran.txt4
tran.txt5
这些文件中的每一个都包含10行,其中有一行信息,类似于以下内容:
12345678910111476
2014123456789813186313338
20141030
20141030
840
3597
840
3597
www.test.com
6068
我希望我的结果看起来是5行回显到一个新文件(test.txt),如下所示:
12345678910111476, 2014123456789813186313338, 20141030, 20141030, 840, 3597, 840, 3597, www.test.com, 6068
这是我目前的代码:
@echo=on
Call :Start > c:\temp\test.log 2>&1
:Start
set tlst=C:\temp\test\tlist.txt
For /F "tokens=*" %%H in (%tlst%) Do (
set Z=%%H
set Counter=1
echo %Z%
echo %Counter%
For /F "tokens=*" %%x in (%Z%) Do (
set "Line_!Counter!=%%x"
echo "Line_!Counter! is %%x
set /a Counter+=1
)
set /a NumLines=Counter - 1
Echo %Line_1%, %Line_2%, %Line_3%, %Line_4%, %Line_5%, %Line_6%, %Line_7%, %Line_8%, %Line_9%, %Line_10%, >> C:\temp\test.txt
:: or, for arbitrary file lengths:
for /l %%x in (1,1,%NumLines%) do echo %%x is !Line_%%x!
)
我目前遇到的是我从第6行的令牌中设置的变量似乎没有坚持......变量看起来像是设置了,但在下面的第8行中我尝试回显变量为空,我的下一个For循环显示%Z%变量为(NULL)。我还尝试将%% H标记回显到临时文件中,然后通过
设置变量set /p Z=<tempfile
但两种方法似乎都有相同的结果。
我也尝试在我的通话中添加SETLOCAL EnableExtensions EnableDelayedExpansion,但我再也看不到任何变化。我现在有点失落,所以任何帮助都会受到赞赏。这是我正在提取的日志文件中的一个片段,每个条目返回相同的错误,第二行只有一个不同的记录:
(
set Z=tran.txt1
set Counter=1
echo
echo
For /F "tokens=*" %x in ((null)) Do (
set "Line_!Counter!=%x"
echo "Line_!Counter! is %x
set /a Counter+=1
)
set /a NumLines=Counter - 1
Echo , , , , , , , , , , 1>>C:\temp\test.txt
for /L %x in (1 1) do echo %x is !Line_%x!
)
如果我错过任何细节,我会提前抱歉,我尽可能清楚完整地了解我正在努力实现的细节以及正在发生的过程。
答案 0 :(得分:0)
你有点认识到你需要延迟扩展,但你没有正确使用它。
正常变量扩展%Counter%
在解析语句时发生,并且整个带括号的DO()块在一次传递中被解析。所以该值在循环内是恒定的。您需要启用延迟扩展并改为使用!Counter!
。 !Z!
,!Line_1!
,!Line_2!
等
当您可以使用!Z!
代替时,我不明白为什么您会为%%H
而烦恼。
你不需要一堆Line_n变量 - 你可以简单地将每个值附加到前一个值的末尾。
你应该在你的CALL之后放一个EXIT / B,这样你就不会第二次进入子程序了。但是你可以简单地在整个循环中加上括号并改为重定向。
以下内容应该有效:
@echo off
setlocal enableDelayedExpansion
set "tlst=c:\temp\test\tlist.txt"
>"c:\temp\test.log" 2>&1 (
for /f "usebackq delims=" %%F in ("%tlst%") do (
set "ln=,"
for /f "usebackq delims=*" %%L in ("%%~F") do (
set "ln=!ln!,%%L"
)
echo(!ln:~2!
)
)
我使用了USEBACKQ选项,以防你得到包含空格的文件路径。
我使用不需要的字符初始化ln
变量,然后将其删除,以便即使文件中没有值也定义变量。
请注意,如果启用了延迟扩展且值包含!
,则FOR变量扩展将会损坏。如果您可能遇到!
,那么必须在循环内打开和关闭延迟扩展,如下所示:
@echo off
setlocal disableDelayedExpansion
set "tlst=c:\temp\test\tlist.txt"
>"c:\temp\test.log" 2>&1 (
for /f "usebackq delims=" %%F in ("%tlst%") do (
set "ln=,"
for /f "usebackq delims=*" %%L in ("%%~F") do (
setlocal enableDelayedExpansion
for "delims=" %%A in ("!ln!") do (
endlocal
set "ln=%%A,%%L"
)
)
setlocal enableDelayedExpansion
echo(!ln:~2!
endlocal
)
)