【问题标题】:Extracting text values from string in batch批量从字符串中提取文本值
【发布时间】:2017-01-11 16:15:35
【问题描述】:

我从批处理文件中生成了以下文本:

FILE:71.jpg 88557: ( 0, 0, 0) #000000 black 535: ( 0, 0,255) #0000FF blue 3617: ( 0,255, 0) #00FF00 lime 315: ( 0,255,255) #00FFFF cyan 9674: (255, 0, 0) #FF0000 red 214: (255, 0,255) #FF00FF magenta 5552: (255,255, 0) #FFFF00 yellow 11536: (255,255,255) #FFFFFF white

我想提取如下值:

8857: black
535: blue
3617: lime
etc..

请问有什么办法可以做到吗?抱歉,我没有批量经验。

【问题讨论】:

  • 这一切都在一条线上吗?您如何知道颜色部分何时完成?
  • 请注意 StackOverflow 不是免费的代码编写服务!分享您的努力并准确描述您遇到的问题!请阅读tour 并了解如何使用本网站!

标签: batch-file text scripting


【解决方案1】:

假设文件File.txt中只有一个行字符串:

@Echo off
Set /P String=<File.txt
Set String=%String:(="%
Call :Sub %String:)="%
Goto :Eof
:Sub
shift
If "%~1"=="" Goto :Eof
Echo %1 | findstr "# ," >Nul 2>&1 && goto :sub
Set var=%1
If "%var:~-1%" equ ":" (set /p =%var% <Nul) Else Echo:%1 
goto :Sub

输出

88557: black
535: blue
3617: lime
315: cyan
9674: red
214: magenta
5552: yellow
11536: white

Set /p 通过输入重定向从 file.txt 中读取一行。
%String:(="% 用双引号交换括号以简化解析。
shift 命令跳过第一个 arg,然后前进到下一个 arg。 sub 中的 findstr 消除了不需要的元素。
if 检查当前参数是否有尾随冒号,如果是则通过 set /p 输出,如果不是简单地回显当前参数,则没有 crlf。

【讨论】:

    【解决方案2】:

    以下是一个非常健壮的脚本,它从作为命令行参数提供的文本文件中提取颜色信息。文本文件甚至可能包含多行。该脚本仅处理以文字字符串FILE: 开头的行,后跟不包含:\SPACE 的字符串(如您的示例中的71.jpg)。所以这里是代码,包括一些解释性的remcmets:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "_FILE=%~1" & rem // (`%~1`: specify input file by command line argument)
    
    rem // Read the input file line by line, split off prefix (`FILE:`):
    for /F "tokens=2,* eol=: delims=: " %%K in ('
        rem/ Filter for lines with matching prefix: ^& ^
        findstr /R /C:"^FILE:[^:\\ ][^:\\ ]*  *[0-9][0-9]*:  *" "%_FILE%"
    ') do (
        rem // Return prefixed file name at `STDERR` stream:
        >&2 echo  **** %%K **** 
        rem // Process current line without prefix in sub-routine:
        call :EXTRACT "%%L"
    )
    
    endlocal
    exit /B
    
    
    :EXTRACT  val_string
        setlocal DisableDelayedExpansion
        rem // Store string argument in variable:
        set "LINE=%~1"
        setlocal EnableDelayedExpansion
        :EXTRACT_LOOP
        rem // Check whether beginning of string matches a colour block:
        cmd /V /C echo(^^!LINE^^! | (> nul ^
            findstr /R /I /C:"^[0-9][0-9]*:  *( *[0-9][0-9]* *, *[0-9][0-9]* *, *[0-9][0-9]* *)  *#[0-9A-F][0-9A-F]*  *[a-z][a-z]*  *"
        ) && (
            rem // String matches, so continue; extract first number and word:
            for /F "tokens=1,6,* delims=:(,)# " %%A in ("!LINE!") do (
                endlocal
                rem // Return number and word extracted from colour block:
                echo(%%A: %%B
                rem // Assign remainder to variable:
                set "LINE=%%C"
                setlocal EnableDelayedExpansion
            )
            rem // Jump back to beginning of loop:
            goto :EXTRACT_LOOP
        )
        endlocal
        endlocal
        exit /B
    

    假设批处理文件保存为extract-colours.bat,文本文件名为sample.txt,运行脚本如下:

    extract-colours.bat "sample.txt"
    

    如果文本文件包含您的示例数据,输出将是这样的:

     **** 71.jpg ****
    88557: black
    535: blue
    3617: lime
    315: cyan
    9674: red
    214: magenta
    5552: yellow
    11536: white
    

    要将结果存储到另一个文本文件中,请使用以下命令行:

    extract-colours.bat "sample.txt" > "result.txt"
    

    由于一对****(此处为71.jpg)之间的标题字符串部分在STDERR流中返回,与输出到STDOUT,该头文件不包含在文件中;要包含它,请将2&gt;&amp;1 附加到上述命令行;如果没有,要取消控制台窗口中的标题,请改为附加 2&gt; nul。阅读本文以了解这一切的含义:Redirection

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多