在for循环中使用usebackq时批处理CSV处理空标记

时间:2016-10-27 12:17:04

标签: csv batch-file

我在处理空标记的问题上找到了很多主题,但是我无法使用它来处理我的代码。我能看到的唯一区别是我正在使用其他人没有的 usebackq ,但是如果我将其删除,其余的代码将无法正常工作。有人能指出我正确的方向吗?

代码应该采用csv,使用存储在 Mitarbeiter.txt 中的另一个值切换第3列中的值,并对最后一个值执行相同的操作在 Lohnarten.txt 中配对,然后将其写入新的csv:

@Echo Off 
SetLocal EnableDelayedExpansion

(Set Datei=lohn_prod.csv)
(Set MA=Mitarbeiter.txt)
(Set LA=Lohnarten.txt)
(Set Ziel=eGecko.csv)

For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%MA%"') Do (
    If Not Defined $[%%A] Set "$[%%A]=%%B") 
For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%LA%"') Do (
    If Not Defined $[%%A] Set "_[%%A]=%%B")

For /F "Delims=" %%X In ("%Datei%") Do (
    Set Line=%%X
    Set Line=!Line:;=";"!
    (For /F "UseBackQ EOL=; Skip=13 Tokens=1-7 Delims=;" %%A In ("!Line!") Do (
        Call Echo=%%~A;%%~B;%%$[%%~C]%%;%%~D;%%~E;%%~F;%%_[%%~G]%%;)
    )
)>%Ziel%
Exit/B

我正在尝试将所有分号分隔符封装在引号中并在将所有内容写入新文件之前将其删除,但这并不起作用。

而不是获得此csv:

15;01.09.2016;105;160,25;1;2100;210;
15;01.09.2016;105;40;1;;217;
15;01.09.2016;105;5;72;;;
15;01.09.2016;107;184;1;2213;210;
15;01.09.2016;107;7,25;1;;213;
15;01.09.2016;107;16;1;;216;

进入这种期望的形式:

15;01.09.2016;40200;160,25;1;2100;101;
15;01.09.2016;40200;40;1;;103;
15;01.09.2016;40200;5;72;;;
15;01.09.2016;40201;184;1;2213;101;
15;01.09.2016;40201;7,25;1;;423;
15;01.09.2016;40201;16;1;;102;

我反而得到这个,如果前面有一个空标记,那么最后一个值会移动到第二个最后位置,因此也不会被 Lohnarten.txt中的值替换/ EM>:

15;01.09.2016;40200;160,25;1;2100;101;
15;01.09.2016;40200;40;1;217;;
15;01.09.2016;40200;5;72;;;
15;01.09.2016;40201;184;1;2213;101;
15;01.09.2016;40201;7,25;1;213;;
15;01.09.2016;40201;16;1;216;;

2 个答案:

答案 0 :(得分:0)

我在这里使用了aschipfls建议,以及另一个问题的解决方案。我不明白,这条线实际上做了什么:

Set Line=%%X;;;;;;;

有人可以向我解释一下吗?

现在可以使用的调整后的代码就是这个(我使用 Line:; =;“而不是 Line:; =”;“”,因为除此之外在第一个未被删除的令牌之后的一个引号标记:

@Echo Off 
SetLocal EnableDelayedExpansion

(Set Datei=lohn_prod.csv)
(Set MA=Mitarbeiter.txt)
(Set LA=Lohnarten.txt)
(Set Ziel=eGecko.csv)

For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%MA%"') Do (
    If Not Defined $[%%A] Set "$[%%A]=%%B") 
For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%LA%"') Do (
    If Not Defined _[%%A] Set "_[%%A]=%%B")

Type NUL > "%Ziel%"
For /F "UseBackQ Delims=" %%X In ("%Datei%") Do (
    Set Line=%%X;;;;;;;
    Set Line="!Line:;=;"!"
    (For /F "EOL=; Tokens=1-7 Delims=;" %%A In ("!Line!") Do (
        Echo=%%~A;%%~B;!$[%%~C]!;%%~D;%%~E;%%~F;!_[%%~G]!;)
    )
)>>%Ziel%
Exit/B

答案 1 :(得分:0)

您的代码中存在一些问题,这让我不相信它会产生您声明的输出(可能只是复制粘贴问题);无论如何,这里是问题:

  • 在第二个if defined循环中的for /F查询中,似乎查询了错误的变量$[%%A],我认为它应该是_[%%A];
  • 而不是Set Line=!Line:;=";"!,您应该写Set Line="!Line:;=";"!",因此每个以分号分隔的项目都包含在""中;然后~变量的for /F修饰符可靠地运行,以便以后删除引号;
  • 重定向部分>的嵌套是错误的,您需要在外部for /F循环而不是内部循环中放置括号,否则,每行都会被重定向,覆盖以前的行;我将重定向部分放在括号内的块的开头,只是因为我更喜欢它,但你可以把它放在块的末尾;顺便说一句,重定向目标应该引用"%Ziel%";
  • UseBackQ选项必须在外部for /F循环中声明,而不是在内部声明;

以下是一些其他问题:

  • 应更改Set语法,以便整个分配表达式出现在""之间,以避免出现特殊字符问题;
  • 由于您已启用延迟展开,因此无需使用Call Echo %%Variable%%,您可以使用Echo !Variable!代替
  • 我更改了缩进和右括号的位置,以便代码变得更清晰;

这是固定的脚本:

@Echo Off
SetLocal EnableDelayedExpansion

Set "Datei=lohn_prod.csv"
Set "MA=Mitarbeiter.txt"
Set "LA=Lohnarten.txt"
Set "Ziel=eGecko.csv"

For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%MA%"') Do (
    If Not Defined $[%%A] Set "$[%%A]=%%B"
)
For /F "Tokens=1-2 Delims=;" %%A In ('FindStr "[0-9]*;.*" "%LA%"') Do (
    If Not Defined _[%%A] Set "_[%%A]=%%B"
)

> "%Ziel%" (
    For /F "UseBackQ Delims=" %%X In ("%Datei%") Do (
        Set "Line=%%X"
        Set Line="!Line:;=";"!"
        For /F "EOL=; Skip=13 Tokens=1-7 Delims=;" %%A In ("!Line!") Do (
            Echo %%~A;%%~B;!$[%%~C]!;%%~D;%%~E;%%~F;!_[%%~G]!;
        )
    )
)
Exit /B