问题描述
我有一些*.bat
文件,其中包含find
命令来提取某些特定行。
Login time : XX:XX
username - XXXXXX
Login time : YY:YY
username - YYYYYYY
使用用户名,免得说:
find /I "XXXXXX" input.txt | find /I "XXXXXX" > output.txt
我能够获得用户名,但不知道如何仅针对搜索到的用户名获得正确的登录时间?
解决方法
find
(和findstr
)无法处理换行符。他们自己处理每条线。因此,您必须编写一个脚本来记住最后一行,检查当前行中的搜索字符串,并在找到搜索字符串的同时打印最后一行和当前行。
我使用findstr
代替了find
,因为它更安全(find "XXXXXX"
也会找到XXXXXXY
)。有关开关findstr /?
,i
和x
的信息,请参见c
。
@echo off
setlocal enabledelayedexpansion
set "search=xxxxxx"
for /f "delims=" %%a in (t.txt) do (
echo %%a|findstr /ixc:"username - %search%" >nul && echo !lastline! %%a
set "lastline=%%a"
)
,
假设您实际上是在windows(cmd.exe
)上工作,而不是在dos(COMMAND.COM
)上工作,则可以使用findstr
,它可以定义多行搜索字符串,尽管仅在匹配的情况下返回第一行,但是无论如何下一条总是一样的,因此可能不需要。
此Windows batch-file显示了我的意思:
@echo off
rem // Get Carriage-Return (CR) character:
for /F %%C in ('copy /Z "%~f0" nul') do set "CR=%%C"
rem // Get Line-Feed (LF) character:
(set LF=^
%= blank line =%
)
rem // Enable delayed expansion to be able to use CR and LF:
setlocal EnableDelayedExpansion
rem /* Specify a multi-line search string,which must literally reflect the actual
rem line-break (that is CR + LF for a DOS/Windows text file); `findstr` returns
rem only the first line when it encounters a match: */
findstr /I /R /C:"!CR!!LF!username - XXXXXX$" "input.txt" > "output.txt"
rem /* This is needed to get the second line of the multi-line match too
rem (replace this by the commented out line in case you expect multiple entries for
rem the searched user,because you would get multiple equal user name entries; the
rem commented out line ensures that there is a single user name entry at the end): */
findstr /I /R /C:"^username - XXXXXX$" "input.txt" >> "output.txt"
rem findstr /I /R /C:"^username - XXXXXX$" "input.txt" | findstr /I /R /V /C:"!CR!!LF!username" >> "output.txt"
N。 B。:
我猜您正在使用两个find
命令来摆脱第一个命令产生的标题;但是,您可以改用以下内容:
rem // Input redirection `<` prevents `find` from returning a header:
find /I "XXXXXX" < "input.txt" > "output.txt"