windows cmd - 解析文件,输出字符范围,查找唯一值

时间:2016-01-18 19:56:09

标签: windows parsing batch-file cmd

这是我的输入文件。

STDEP:DEV=UPDR-5377&&-5407;
UPDR-5381       BUSY                   H'0   ALNEONO     -
UPDR-5382       IDLE                   H'0   ALNEONO     -

UPDR-53770      BLOC  MBL         NC   H'0               -
UPDR-53771      BLOC  MBL         NC   H'0               -
UPDR-53772      BLOC  MBL         NC   H'0               -
UPDR-53773      BLOC  MBL         NC   H'0               -
UPDR-53774      BLOC  MBL         NC   H'0               -

UPDR-5699       LIBL                   H'1   VBYABYO     MAINT
UPDR-5700       LIBL                   H'1   VBYABYO     MAINT
UPDR-5701       LIBL                   H'1   VBYABYO     MAINT
UPDR-5702       LIBL                   H'1   VBYABYO     MAINT

UPDR-4253       BLOC  ABL              H'1   ODUAHRO     MAINT
UPDR-4254       BLOC  ABL              H'1   ODUAHRO     MAINT
UPDR-4255       BLOC  ABL              H'1   ODUAHRO     MAINT
UPDR-6689       BLOC  ABL              H'1   ODUAHRO     MAINT

我需要解析它,从46到52之间的每一行获取值。最后,唯一值应存储在文本文件中。对于此输入文件,输出应为:

type some_file.txt
ALNEONO VBYABYO ODUAHRO

我面临的挑战是需要在Windows cmd行中完成。最远的我已经做到了这一步

for /F "tokens=* delims=" %a in (KHMSC4_DELETE_check.txt) do @echo %a:~46,7%

不按指定间隔切割线。任何想法都受到高度赞赏。

3 个答案:

答案 0 :(得分:1)

变量子字符串替换不适用于for个变量(%a%%a

假设您的文本文件使用空格格式化,而不是标签:

@echo off
setlocal enabledelayedexpansion
rem define output variable (doesn't work with empty varable, so insert a space):
set "output= "
rem parse the file line for line:
for /F "tokens=* delims=" %%a in (somefile.txt) do (
  rem put the line into a variable to work with it:
  set "string=%%a"
  rem get the desired location (again add a space in case the string is empty (line too short)):
  set "string=!string:~45,7! "
  rem remove all spaces (the following line doesn't work as intended when string is empty):
  set "string=!string: =!"
  rem check, if string is already in output, if not add it
  rem by (doing that, replace all double spaces (from short lines) in output with one space)
  rem (again, the "set output=" doesn't work with empty "output")
  echo !output!|find "!string!" >nul || set "output=!output:  = ! !string!"
)
echo the string, stripping the leading space:
echo %output:~1%

这使用子字符串替换,在set /pdelayed expansion||中进行了解释,如果上一个命令(find)失败,则作为“”,然后

另请注意dbenham的评论:

  

...如果任何行包含!,这将无法正常工作...此外,这将跳过以;

开头的行

我没有打扰,因为您的输入文件似乎没有这个问题。

答案 1 :(得分:1)

这是一行:

cmd /V:ON /C "(for /F "delims=" %a in (input.txt) do @set "a=%a" & set "a[!a:~45,7!]=1") & for /F "skip=1 tokens=2 delims=[]=1" %a in ('set a[') do @< NUL >> output.txt set /P "=%a "

示例:

C:\> del output.txt

C:\> cmd /V:ON /C "(for /F "delims=" %a in (input.txt) do @set "a=%a" & set "a[!
a:~45,7!]=1") & for /F "skip=1 tokens=2 delims=[]=1" %a in ('set a[') do @< NUL
>> output.txt set /P "=%a "

C:\> type output.txt
ALNEONO ODUAHRO VBYABYO

编辑:另一种更简单的方法:

cmd /V:ON /C "set "a= " & (for /F "delims=" %b in (input.txt) do @set "b=%b" & for /F %c in ("!b:~45,7!") do @if "!a:%c=!" equ "!a!" set "a=!a!%c ") & echo !a:~1,-1!> output.txt"

答案 2 :(得分:0)

感谢您的所有答案我已经尝试过您的解决方案,但它们都有效。在昨天失去了半天之后,这就是必杀技。

最后,我将尝试从.cmd文件中运行所有命令,因为有时它会卡在for循环中。由于我只能访问终端,我想知道是否有任何方法

  1. 打开一个文件,类似于unix中的vi?
  2. 发送所有行(包括特殊字符)
  3. 关闭文件
  4. 运行它
  5. 这是我的完整cmd列表:

    @echo off
    IF EXIST KHMSC4_DELETE_check.txt del /F KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo             !MSC PRECHECK REPORT STARTS HERE^! >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo !STDEP:DEV=UPDR    --- DELETE PART    ---^! >> KHMSC4_DELETE_check.txt
    mml "STDEP:DEV=UPDR-6657&&-6687;" | findstr /I "UPDR" >> KHMSC4_DELETE_check.txt
    mml "STDEP:DEV=UPDR-6689&&-6719;" | findstr /I "UPDR" >> KHMSC4_DELETE_check.txt
    mml "STDEP:DEV=UPDR-6721&&-6751;" | findstr /I "UPDR" >> KHMSC4_DELETE_check.txt
    mml "STDEP:DEV=UPDR-6753&&-6783;" | findstr /I "UPDR" >> KHMSC4_DELETE_check.txt
    For /F %%I in ('"type KHMSC4_DELETE_check.txt | findstr /I "BLOC LIBL" | findstr /v "DEVICES" | find /c "UPDR""') Do Set NR_BLOC=%%I
    
    setlocal enabledelayedexpansion
    set "output= "
    for /F "tokens=* delims=" %%a in (KHMSC4_DELETE_check.txt) do (
      set "string=%%a"
      set "string=!string:~45,7! "
      set "string=!string: =!"
      echo !output!|find "!string!" >nul || set "output=!output:  = ! !string!"
    )
    
    
    echo: >> KHMSC4_DELETE_check.txt
    echo ^^!NTCOPP:SNT-RTDMA    --- DELETE PART    ---^^! >> KHMSC4_DELETE_check.txt
    echo: >> WINFIOL - DISABLE PAUSE AT EXCHANGE ERRORS FROM OPTIONS -> PREFERENCES -> TRAFFIC SETUP -> PAUSE
    mml "NTCOP:SNT=RTDMA-636;" | findstr /I "RTDMA" | findstr /V "NTCOP" >> KHMSC4_DELETE_check.txt
    mml "NTCOP:SNT=RTDMA-637;" | findstr /I "RTDMA" | findstr /V "NTCOP" >> KHMSC4_DELETE_check.txt
    mml "NTCOP:SNT=RTDMA-638;" | findstr /I "RTDMA" | findstr /V "NTCOP" >> KHMSC4_DELETE_check.txt
    mml "NTCOP:SNT=RTDMA-639;" | findstr /I "RTDMA" | findstr /V "NTCOP" >> KHMSC4_DELETE_check.txt
    
    
    echo: >> KHMSC4_DELETE_check.txt
    echo ^^!NUMBER OF DEVICES BLOCKED - DELETE part: %NR_BLOC%. FIRST 5 PRINTED BELOW^^! >> KHMSC4_DELETE_check.txt
    type KHMSC4_DELETE_check.txt | findstr /I "BLOC LIBL" | findstr /v "DEVICES" | findstr/n ^^ | findstr "^[0-5]:" >> KHMSC4_DELETE_check.txt"
    echo: >> KHMSC4_DELETE_check.txt
    echo ^^!LIST OF ROUTES FOR DELETE PART^^! >> KHMSC4_DELETE_check.txt
    echo %output:~1% >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo ^^!BLURP AND NUMBER OF DEVICES^^! >> KHMSC4_DELETE_check.txt
    mml "BLURP:R=VIUAVIO;" | findstr /v "BLOCKING END" >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    mml "STRSP:R=VIUAVIO;" | findstr /v "DEVICE END" >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txt
    echo ^^!MSC PRECHECK REPORT ENDS HERE^^! >> KHMSC4_DELETE_check.txt
    echo: >> KHMSC4_DELETE_check.txtecho: >> KHMSC4_DELETE_check.txt
    type KHMSC4_DELETE_check.txt
    del KHMSC4_DELETE_check.txt
    

    由于感叹号

    ,这就是我的屏幕报告的外观

    This is how my report looks because of the exclamation marks

    再次感谢您的支持!