【问题标题】:Can't get full second parameter in a for /f loop无法在 for /f 循环中获取完整的第二个参数
【发布时间】:2018-06-12 13:15:13
【问题描述】:

我有一个这样的文件:

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 与

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 与

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 与

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

002.txt 与

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

似乎“eol=;tokens=1,* delims=;”无法正常工作,忘记了“tokens”编译指示的第二个参数应该占用输入行的其余部分。 为什么?有什么建议吗?

谢谢!

【问题讨论】:

  • 你能不能只运行这个For /F "Tokens=1* Delims=;" %%A In (myfilename.csv) Do (Echo %%A;%%B)>>"%%A.txt",然后将你的标题添加到每个?
  • 删除eol=;。
  • @AlexP, eol=; 实际上在这里禁用了eol 字符,因为它与具有更高优先级的分隔符(之一)相同...跨度>
  • Tokens=1,* 工作正常,但问题是由call 的未引用参数引起的,所以%2 被第一个; 分割,这只是一个普通的标记分隔符cmd;使用call :doTheWork "%%a" "%%b" 并分别读取%~1 和%~2 之类的参数,因此参数被保留...
  • 我做了一个新测试,在其中我做了一些更改:'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!)'控制台是对的,两个参数显示如预期。看来问题出在子程序的传递过程中...

标签: batch-file for-loop


【解决方案1】:

问题不是由for /F 及其tokens= 选项字符串引起的,而是由call 的未引用参数引起的,因此%2 在第一个; 处被拆分,这不过是一个正常的标记cmd 中的分隔符(就像 SPACE、TAB、, 和 =)。

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

call "%%a" "%%b"

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

echo %~1;%~2

最后,我建议您将 set 语法更改为:

set "header=field1;field2;field3;field4;field5;field6;field7;field8"

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

【讨论】:

    【解决方案2】:

    根据我最初的评论和你的新测试,评论:

    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。

    无论内容如何,​​我都建议使用双引号,但是根据已知信息,我将其保留为必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2018-11-06
      • 2014-08-28
      相关资源
      最近更新 更多