我有一个脚本可以提取以下行:
THIS_IS_A_LINE:=
THIS_IS_A_LINE2:=
并将所有相同的类型输出到另一个.txt文件中:
THIS_IS_A_LINE
THIS_IS_A_LINE2
脚本如下:
set "file=%cd%/Config.mak"
set /a i=0
set "regexp=.*:=$"
setlocal enableDelayedExpansion
IF EXIST Source_List.txt del /F Source_List.txt
for /f "usebackq delims=" %%a in ("%file%") do (
set /a i+=1
call set Feature[!i!]=%%a
)
cd .. && cd ..
rem call echo.!Feature[%i%]!
for /L %%N in (1,1,%i%) do (
echo(!Feature[%%N]!|findstr /R /C:"%regexp%" >nul && (
call echo FOUND
call set /a j+=1
call set Feature_Disabled[%j%]=!Feature[%%N]:~0,-2!
call echo.!Feature_Disabled[%j%]!>>Source_List.txt
) || (
call echo NOT FOUND
)
)
endlocal
我还有另一个脚本可以提取以下行:
THIS_IS_ANOTHER_LINE:= TRUE
THIS_IS_ANOTHER_LINE2:=真 ...
并将所有相同的类型输出到另一个.txt文件中:
THIS_IS_ANOTHER_LINE
THIS_IS_ANOTHER_LINE2 ...
脚本如下:
set "file=%cd%/Config.mak"
set /a i=0
set "regexp=.*:=true$"
setlocal enableDelayedExpansion
IF EXIST Source_List2.txt del /F Source_List2.txt
for /f "usebackq delims=" %%a in ("%file%") do (
set /a i+=1
call set Feature[!i!]=%%a
)
cd .. && cd ..
rem call echo.!Feature[%i%]!
for /L %%N in (1,1,%i%) do (
echo(!Feature[%%N]!|findstr /R /C:"%regexp%" >nul && (
call echo FOUND
call set /a j+=1
call set Feature_Disabled[%j%]=!Feature[%%N]:~0,-6!
call echo.!Feature_Disabled[%j%]!>>Source_List2.txt
) || (
call echo NOT FOUND
)
)
endlocal
尽管如此,还有第三种包含数字的行(也是一些十六进制值),例如:
THIS_IS_AN_UNPROCESSED_LINE:= 0xA303
THIS_IS_AN_UNPROCESSED_LINE2:= 1943
THIS_IS_AN_UNPROCESSED_LINE3:= HELLO_DOOD_CAN_YOU_PARSE_ME
所以我需要这种方式将这些行提取到另一个.txt文件中,例如:
THIS_IS_AN_UNPROCESSED_LINE:= 0xA303
THIS_IS_AN_UNPROCESSED_LINE2:= 1943
THIS_IS_AN_UNPROCESSED_LINE3:= HELLO_DOOD_CAN_YOU_PARSE_ME
所以基本上提取不属于那种的行:
THIS_IS_AN_UNPROCESSED_LINE:=
或
THIS_IS_AN_UNPROCESSED_LINE:= TRUE
但保留行条目的两边。
我知道正则表达式必须有一些技巧,但我无法找到它。
答案 0 :(得分:0)
你使代码变得比它需要的复杂得多。无需在文件中创建每行的数组。
如果在第一个:
之前没有其他=
或:=
,那么您可以使用FINDSTR
打印出包含字符串的所有行,然后是{ {1}}。 :=
可以捕获每个匹配行并将其解析为FOR /F
之前和之后的部分,然后:=
语句可以对三种不同类型的行进行分类。
我使用IF
打开主代码块之外的所有三个输出文件以提高性能,然后我使用n>
语法将每个输出定向到相应的已打开文件。我使用高编号文件句柄来避免Why doesn't my stderr redirection end after command finishes? And how do I fix it?中描述的问题。
&n>
以上内容会忽略@echo off
setlocal
set "file=Config.mak"
set /a "empty=7, true=8, unprocessed=9"
%empty%>empty.txt %true%>true.txt %unprocessed%>unprocessed.txt (
for /f "delims=:= tokens=1*" %%A in ('findstr /r "^[^:=][^:=]*:=" "%file%"') do (
if "%%B" equ "" (
>&%empty% (echo %%A)
) else if "%%B" equ "true" (
>&%true% (echo %%A)
) else (
>&%unprocessed% (echo %%A:=%%B)
)
)
)
之前包含:
或=
的行,如果:=
之后的第一个字符为:=
,它将无法正常工作或:
。我认为这应该不是问题。
使用PowerShell,VBScript或JScript编写一个非常有效的解决方案可以相对容易地消除限制。
您也可以使用JREPL.BAT - a powerful and efficient regular expression text processing command line utility。 JREPL.BAT是纯脚本(混合批处理/ JScrpt),可以在任何Windows机器上从XP开始本地运行,不需要第三方exe。 JREPL比任何纯批处理解决方案都快得多,特别是如果文件很大的话。
这是一个JREPL解决方案
=
如果您要做的就是将线条分类为三个不同的文件,而不必担心剥离空行和真行的@echo off
setlocal
set repl=^
$txt=false;^
if ($2=='') stdout.WriteLine($1);^
else if ($2=='true') stderr.WriteLine($1);^
else $txt=$0;
call jrepl "^(.+):=(.*)$" "%repl%" /jmatchq^
/f Config.mak /o unprocessed.txt >empty.txt 2>true.txt
和:=true
部分,那么就有一个非常简单的纯粹批量解决方案只使用FINDSTR。
:=