我试图编写一个批处理可执行文件,该文件从例如.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
答案 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 /A
或IF ... GTR ...
等)时,批处理文件会将前导零视为八进制:010
将被视为8
。为了允许十进制数字中的前导零,我们:
NUM
。 08
将成为00008
; 100
将变成000100
等。!NUM:~-3,3!
包含NUM
的后三个字符。由于执行了前面的步骤,因此将始终填充零(00008
-> 008
; 000100
-> 100
)。 NUM
的值由1
替换,后跟这三个字符(例如1008
或1100
)。SET /A
将值减少1000(例如8
或100
)。现在可以在极限测试中安全地使用它。输入文件为:
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)
如果我不希望只返回实例后跟数字0
至100
,这就是我要这样做的方式。
@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