批处理:从.txt文件的特定变量中回显所有行

时间:2019-10-23 14:20:04

标签: batch-file

我试图编写一个批处理可执行文件,该文件从例如.txt文件中查找并回显特定行:“ Rating.RESP:”。评分:50。数字从0到100,我希望控制台提示所有变量,并且我不想将其复制到另一个txt文件。

到目前为止,我正在尝试使用findstr:

for /F %%i in (data.txt) do (
echo %%i
findstr /m /c:"Rating.RSP: [0-100]"%%i  
)

有什么提示吗?如果这行得通,我将能够进一步扩展批处理可执行文件。


基于@Gerhard的帮助,我编写了以下代码:

set /p file=Drag data file in here.

echo.
for /F "delims=" %%i in ('type %file% ^| findstr /m "Rating.RESP: "') do echo %%i

结果是“ Rating.RESP:##”的列表

接下来,我试图读取%% i并在其超过75或低于25时回显警告。有什么想法吗?我在考虑提取子字符串的最后两个字符并检查其是否在阈值之内(或之外)。暂时不需要帮助,我正在尝试自己解决问题。再次感谢您提供有关Rating.RESP的帮助。


样本输入文件:

*** Header End ***
    Level: 2
    *** LogFrame Start ***
    list: 1
    Procedure: proc
    leftanchor: Alert
    rightanchor: Suf
    XTime: 09:55:25
    list.Cycle: 1
    list.Sample: 1
    Running: list
    Scale1.RT: 2054
    Scale1.RESP: 1
    Response: t056
    Rating.RESP: 56
    *** LogFrame End ***
    Level: 2
    *** LogFrame Start ***
    list: 2
    Procedure: proc
    leftanchor: Kalm
    rightanchor: Opgewonden
    XTime: 09:55:28
    list.Cycle: 1
    list.Sample: 2
    Running: list
    Scale1.RT: 861
    Scale1.RESP: 1
    Response: t050
    Rating.RESP: 50

2 个答案:

答案 0 :(得分:1)

您最初的问题有点模棱两可:从注释中,我认为“ 找到并回显特定行:“ Rating.RESP:” ”比“ 发现并回显”更好。 echo是包含特定字符串的所有行:“ Rating.RESP:” 。有了这个假设,再加上您对检测超出范围的值的其他评论,我认为可以解决以下问题:

alert.bat

@echo off
    setlocal
    set LOW_LIMIT=25
    set HIGH_LIMIT=75

    set /p file=Drag data file in here.

    for /f "usebackq tokens=1,2" %%a in ( `findstr "Rating.RESP: " "%file%"` ) do (
        setlocal enabledelayedexpansion
        set "WARN="
        if %%b LSS  %LOW_LIMIT% set "WARN=  ** Value too low **"
        if %%b GTR %HIGH_LIMIT% set "WARN=  ** Value too high **"
        echo %%a%%b!WARN!
    )

带有一个包含以下内容的文件:

something else
something else
Rating.RESP: 10
something else
something else
Rating.RESP: 50
something else
something else
Rating.RESP: 80
something else
something else

这将产生输出:

C:>alert.bat
Drag data file in here.data.txt
Rating.RESP:10  ** Value too low **
Rating.RESP:50
Rating.RESP:80  ** Value too high **

注释/假设:

  • 不需要type文件并将其通过管道传输到findstr:我们可以在命令行中提供文件。
  • 使用usebackq选项可以使用双引号(在字符串中都可以找到,如有必要,还可以使用文件名)。这不是严格必要的,但通常可以防止出现问题。
  • [更新]我已从该答案的原始版本中删除了/b,因为Rating.RESP并不总是(永远?)从行首开始。
  • tokens=1,2与默认定界符(空格或制表符)一起使用将匹配的行分为Rating.RESP(在%%a中)和数值(在%%b中)。 / li>
  • 当前代码假设,用Rating.RESP:行将仅 后跟有效数字,并且没有前导零(例如07)。如果这些假设中的任何一个都不成立,则将需要一些额外的代码。 (前导零的问题是CMD将它们视为八进制,因此09被视为无效数字。)
  • 使用setlocal enabledelayedexpansion可以使set的值WARN 并在for命令的正文中使用。< / li>

增强检查

如果需要 检测无效数字或处理带有前导零的数字,则将执行以下操作:

@echo off
    setlocal
    set LOW_LIMIT=25
    set HIGH_LIMIT=75

    set /p file=Drag data file in here.

    for /f "usebackq tokens=1,2" %%a in ( `findstr "Rating.RESP: " "%file%"` ) do (
        setlocal enabledelayedexpansion
        set "WARN="
        for /f "delims=0123456789 tokens=1" %%x in ("%%b") do if not "%%x" == "" set "WARN=  ** Invalid number **"
        if not defined WARN (
            set "NUM=000%%b"
            set "NUM=1!NUM:~-3,3!"
            set /a NUM=!NUM!-1000
            if !NUM! LSS  %LOW_LIMIT% set "WARN=  ** Value too low **"
            if !NUM! GTR %HIGH_LIMIT% set "WARN=  ** Value too high **"
        )
        echo %%a%%b!WARN!
    )
~

注释

  • for /f "delims=0123456789 tokens=1"行检测到%%b中的非数字。通过使用所有数字作为分隔符,纯数字字符串会将%%x设置为空字符串(因为除了 分隔符外没有其他字符)。但是,如果有任何非数字,则将提取它们的第一轮,并且%%x将不再为空。仅在不产生警告的情况下才执行主循环的其余部分。
  • 在处理数字(例如SET /AIF ... GTR ...等)时,批处理文件会将前导零视为八进制:010将被视为8。为了允许十进制数字中的前导零,我们:
    • 首先创建带有“足够”前导零的NUM08将成为00008100将变成000100等。
    • 表达式!NUM:~-3,3!包含NUM的后三个字符。由于执行了前面的步骤,因此将始终填充零(00008-> 008000100-> 100)。 NUM的值由1替换,后跟这三个字符(例如10081100)。
    • 现在没有前导零,我们使用SET /A将值减少1000(例如8100)。现在可以在极限测试中安全地使用它。

输入文件为:

    Rating.RESP: 15
    Rating.RESP: 85
    Rating.RESP: 09
    Rating.RESP: 026
    Rating.RESP: 26
    Rating.RESP: xx
    Rating.RESP: 9x
    Rating.RESP: x9

我们现在得到:

Rating.RESP:15  ** Value too low **
Rating.RESP:85  ** Value too high **
Rating.RESP:09  ** Value too low **
Rating.RESP:026
Rating.RESP:26
Rating.RESP:xx  ** Invalid number **
Rating.RESP:9x  ** Invalid number **
Rating.RESP:x9  ** Invalid number **

(对于原始版本,026将被视为八进制,变为22十进制,并会触发“过低”警告)。

答案 1 :(得分:0)

如果我不希望只返回实例后跟数字0100,这就是我要这样做的方式。

@Find "Rating.RSP:"<"data.txt"

如果需要,也可以使其不区分大小写:

@Find /I "Rating.RSP:"<"data.txt"

[编辑/] 由于修改/扩展的问题而进行更新

@Set /A Lo=25,Hi=75
@Set "_="&Set /P "_=Drag file here >"
@If Defined _ For /F "Tokens=2Delims=:" %%A In ('Find "Rating.RESP: "^<"%_%"'
)Do @If %%A Lss %Lo% (Echo Value too low:%%A
)Else If %%A Gtr %Hi% Echo Value too high:%%A
@Pause