无法在for / f循环中获得完整的第二个参数

时间:2018-06-12 13:15:13

标签: batch-file for-loop

我有这样的文件:

001;0009;024;165748;0634;;CAPO;
001;0009;030;143366;0633;;CAPO;
001;0009;030;160671;0644;31/05/2018;PART;
001;0009;030;160857;0644;;PART;
001;0009;031;168135;0644;;PART;
001;0009;046;168085;0612;;CAPO;
002;0002;007;286169;4013;21/03/2018;PART;
002;0002;009;053175;4013;;PART;
002;0002;026;241075;4023;01/02/2018;PART;
002;0002;026;241076;4023;01/02/2018;PART;
002;0002;026;241102;4023;;PART;

我需要的是创建多个文件,当前3个字符发生变化时会被破坏,每个文件都以3个第一个字符命名。 所以,按照这个例子,我将有

001.txt with

001;0009;024;165748;0634;;CAPO;
001;0009;030;143366;0633;;CAPO;
001;0009;030;160671;0644;31/05/2018;PART;
001;0009;030;160857;0644;;PART;
001;0009;031;168135;0644;;PART;
001;0009;046;168085;0612;;CAPO;

002.txt with

002;0002;007;286169;4013;21/03/2018;PART;
002;0002;009;053175;4013;;PART;
002;0002;026;241075;4023;01/02/2018;PART;
002;0002;026;241076;4023;01/02/2018;PART;
002;0002;026;241102;4023;;PART;

我用这批产品部分实现了它:

@@echo off
setlocal ENABLEDELAYEDEXPANSION
@echo Wait please...
set header=field1;field2;field3;field4;field5;field6;field7;field8
set craold=""
set cranow=""
FOR /F "eol=; tokens=1,* delims=;" %%a in (myfilename.csv) do call :doTheWork %%a %%b
@echo Ended
pause
GOTO :EOF

:doTheWork
set cranow=%1
IF NOT !craold!==!cranow! (
   call :createFile %cranow%
   set craold=!cranow!
)
set recfilename=%craold%.txt
@echo %1;%2 >> %recfilename%
GOTO :END

:createFile
set myfilename=%1.txt
@echo %header% > %myfilename%
@echo CRA: %1
GOTO :END

:END

我的问题是,在我的文件中,我发现了这个:

001.txt with

field1;field2;field3;field4;field5;field6;field7;field8
001;0009
001;0009
001;0009
001;0009
001;0009
001;0009

002.txt with

field1;field2;field3;field4;field5;field6;field7;field8
002;0002
002;0002
002;0002
002;0002
002;0002

似乎" eol =; tokens = 1,* delims =;"没有正常工作,忘记了"令牌的第二个参数" pragma应该占用输入行的其余部分。 为什么?建议?

谢谢!

2 个答案:

答案 0 :(得分:0)

问题不是由for /F及其tokens=选项字符串引起的,而是由call的不带引号的参数引起的,因此%2在第一个{{1}处分裂这只是;中的常规标记分隔符(就像 SPACE TAB cmd,

要更正此问题,请引用=参数以保护令牌分隔符和其他特殊字符:

call

并阅读这样的参数以删除引号:

call "%%a" "%%b"

最后,我建议您将echo %~1;%~2 语法更改为:

set

这里的引号不会成为变量值的一部分,但是特殊字符会受到保护。

答案 1 :(得分:0)

根据我的初步评论并给出您的新测试,作为评论

FOR /F "tokens=1,* delims=;" %%a in (rapporti.csv) do (
    set param1=%%a
    set param2=%%b
    @echo In loop !param1! !param2!
    call :doTheWork !param1! !param2!
)

无需设置任何变量,因此预先设置延迟扩展,因为您不修改返回的元变量。

您应该在Call命令中双重引用传递的参数,以保护特殊字符,例如......
分号, ;

For /F "Tokens=1* Delims=;" %%A In (rapporti.csv) Do (
    Echo In loop %%A;%%B
    Call :doTheWork %%A "%%B"
)

:doTheWork中,您可以根据需要从%2删除周围的双引号,并将其引用为%~2

无论内容如何,​​我都建议使用双引号,但我已将其保留为基于已知信息所必需的内容。