Windows批处理文件计数令牌数

时间:2017-03-10 11:46:46

标签: windows batch-file cmd

我有这个批处理文件:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF EXIST OPERATORS_FULL.csv DEL OPERATORS_FULL.csv
IF EXIST OPERATORS_FULL.tmp DEL OPERATORS_FULL.tmp

FOR %%A IN ( OPERATORS_*.csv ) DO (
    :: get attribute from filename
    SET "attr=%%A"
    SET "attr=!attr:OPERATORS_=!"
    SET "attr=!attr:.csv=!"
    :: split string to get date suffix
    FOR /F "tokens=1,2 delims=_" %%G IN ( "!attr!" ) DO (
        SET attr=%%G
        SET date_=%%H
    )
    :: dump CSVs, skipping each header line, adding the attributes from the filename
    FOR /F "skip=1 tokens=*" %%G IN ( %%A ) DO ECHO %%G;!attr!;!date_! >> OPERATORS_FULL.tmp
)

REN OPERATORS_FULL.tmp OPERATORS_FULL.csv

attr值是可变的,它可以包含1,2,3,4,...的“_”字符。 所以tokens=1,2每次都不是功能上的。 我想要“attr”变量的最后一个标记。

有什么建议吗?

更新

我试过了:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF EXIST Operatori_FULL.csv DEL Operatori_FULL.csv
IF EXIST Operatori_FULL.tmp DEL Operatori_FULL.tmp

FOR %%A IN ( Operatori_*.csv ) DO (
    :: get attribute from filename
    SET "attr=%%A"
    SET "attr=!attr:Operatori_=!"
    SET "attr=!attr:.csv=!"
        set "date_=!attr!"
:loop
        if "!date_:_=!" == "!date_!" goto :gotdate
        for /f "delims=_ tokens=1,*" %%g in ("!date_!") do echo %%h

pause
        goto :loop
:gotdate
        :: dump CSVs, skipping each header line, adding the attributes from the filename
    FOR /F "skip=1 tokens=*" %%G IN ( %%A ) DO ECHO %%G;!attr!;!date_! >> Operatori_FULL.tmp
)

REN Operatori_FULL.tmp Operatori_FULL.csv

但是片段只删除字符串的第一部分(A2A _)

3 个答案:

答案 0 :(得分:2)

此代码从attr变量中提取最后一个标记,并将其存储在date_变量中:

    rem split string to get date suffix
    set "newAttr="
    set "date_="
    FOR %%G IN ( "!attr:_=" "!" ) DO (
        SET "newAttr=!newAttr!_!date_!"
        SET "date_=%%~G"
    )
    SET "attr=!newAttr:~2!"

如果您只需要最后一个令牌,则代码更简单:

FOR %%G IN ( "!attr:_=" "!" ) DO SET "date_=%%~G"

答案 1 :(得分:0)

希望这将接近您想要的(不确定attr是否符合您的要求):

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF EXIST Operatori_FULL.csv DEL Operatori_FULL.csv
IF EXIST Operatori_FULL.tmp DEL Operatori_FULL.tmp

FOR %%A IN ( Operatori_*.csv ) DO (
    :: get attribute from filename
    SET "attr=%%A"
    SET "attr=!attr:Operatori_=!"
    SET "attr=!attr:.csv=!"
    set "date_=!attr!"
    call :getLast
    :: dump CSVs, skipping each header line, adding the attributes from the filename
    FOR /F "skip=1 tokens=*" %%G IN ( %%A ) DO ECHO %%G;!attr!;!date_! >> Operatori_FULL.tmp
)

REN Operatori_FULL.tmp Operatori_FULL.csv
goto :eof

:getLast
    if "!date_:_=!" == "!date_!" goto :eof
    for /f "delims=_ tokens=1,*" %%g in ("!date_!") do set "date_=%h"
    goto :getLast

子例程getLastdate_剥离到其最后一个组件(由下划线分隔)。它的操作是:虽然在date_中有一个下划线,但它将它分成"第一个令牌"并且"所有其余的"并将date_设置为"其他所有"。如果没有(更多)下划线,date_将留下其原始值的最后一个下划线分隔组件。

"强调剥离代码"需要成为一个"子程序"因为你不能(据我所知)在外部for循环中使用标签。

答案 2 :(得分:0)

这是一个可能的解决方案,它会暂时用换行符替换每个_

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "STRING=%~1" & rem // (first argument is taken as input string)
set "CHAR=_"     & rem // (this is the character of interest)
rem // Build line-break:
(set ^"LF=^
%= empty line =%
^")

rem /* Replace each predefined character by a line-break,
rem    and enclose every line string portion within `""`;
rem    these quotation marks are needed to handle empty strings: */
setlocal EnableDelayedExpansion
if defined STRING set ^"STRING=^"!STRING:%CHAR%=^"^%LF%%LF%^"!^"^"
rem /* Loop through all the lines in the modified string and
rem    assign each line string portion to a variable with
rem    the surrounding `""` removed; when the loop is finished,
rem    the last line is stored in the variable: */
for /F delims^=^ eol^= %%S in ("!STRING!") do (
    endlocal
    set "LAST=%%~S"
    setlocal EnableDelayedExpansion
)
rem // Return string portion behind last predefined character:
echo(!LAST!
endlocal

endlocal
exit /B