使用cmd prompt findstr仅输出字符串中的某些字符集

时间:2015-08-05 16:47:38

标签: windows cmd

使用cmd提示符,我尝试使用 findstr 功能从txt文件输出某些条件。 我的txt文件包含.exe名称列表,包括注释。有很多 - 我只想解析" name.exe"每一行。 以下是txt文件中不同行的示例

C:\\Programme\\Windows Media Player\\mplayer2.exe""=dword:00000000
HOPSTER.EXE; Hopster

其中,我只想要" mplayer2.exe"和" hopster.exe"要包含在打印输出中。 相反,我收到了这个:

脚本findstr "*.exe" Exies.txt

输出:

.\Exies.txt:""C:\\Programme\\Windows Media Player\\mplayer2.exe""=dword:00000000

.\Exies.txt:HOPSTER.EXE; Hopster

我能够使用此脚本提取一些项目,findstr /e ".exe" Exies.txt, 但我遇到上面其他例子的问题。

有任何帮助吗?谢谢,麻烦您了。

2 个答案:

答案 0 :(得分:1)

我不认为你只能使用findstr(我不知道任何FINDSTR输出格式会让你只打印匹配的模式)。

相反,您可以使用PowerShell中的select-string:

C:\>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\> select-string -Path Exies.txt -Pattern "([a-z0-9]+)\.exe" -AllMatches | % { $_.Matches } | % { $_.Value }
mplayer2.exe
HOPSTER.EXE

PS C:\>

答案 1 :(得分:0)

这是一个纯粹的批处理解决方案(代码中有很多解释性rem - arks,所以不要对程度感到震惊。)
最棘手的部分是使偏移位置超出" .exe"用于正确截断从Exies.txt的每一行读取的字符串的扩展名,并确定文件名的起始位置:

@echo off
setlocal EnableDelayedExpansion
rem regular expression for `findstr` which means:
rem a string consisting of a sub-string with at least one character,
rem NOT containing any of '\?*/:<>"', followed by ".exe";
rem such strings are considered as valid executable file names
set REGEX="[^\\?\*/:<>|\""]*[^\\?\*/:<>|\""]\.exe"
rem parse the output of `findstr` with a `for /F` loop
rem (note that `findstr` is told to do case-insensitive searches)
for /F "tokens=*" %%F in ('findstr /I /R %REGEX% Exies.txt 2^> nul') do (
  rem assign a single matching line to variable `LINE`
  set "LINE=%%F"
  rem call sub-routine to retrieve length of string portion after the
  rem (first) occurrence of ".exe"; the length is also equal to the
  rem character offset of the string portion after the ".exe" occurrence
  call :STRLEN "!LINE:*.exe=!" LEN > nul
  rem use another `for` loop to truncate `LINE` after ".exe";
  rem so afterwards we have everything up to the ".exe" portion
  for %%A in (!LEN!) do (
    set "LINE=!LINE:~,-%%A!"
  ) & rem next %%A
  rem replace double-quotes '"' and colons ':' by backslashes '\'
  set "LINE=!LINE:"=\!
  set "LINE=!LINE::=\!"
  rem wrap around another `for` loop to extract the file name portion
  rem (this is done to remove any paths from the "*.exe" file name)
  for %%B in ("!LINE!") do (
     set "LINE=%%~nxB"
  ) & rem next %%B
  rem safety check if extracted "*.exe" file name still matches the
  rem regular expression (necessary if ".exe" occurs twice in a line)
  echo !LINE! | findstr /I /R %REGEX% > nul 2>&1
  if not ErrorLevel 1 (
    rem output final "*.exe" file name
    echo !LINE!
  ) & rem end if
) & rem next %%F
endlocal
exit /B

:STRLEN
rem this constitutes a sub-routine to get the length of a string
setlocal EnableDelayedExpansion
set "STR=%~1"
if "%STR%" EQU "" (
  set /A LEN=0
) else (
  set /A LEN=1
  for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if not "!STR:~%%I!" EQU "" (
      set /A LEN+=%%I
      set "STR=!STR:~%%I!"
    ) & rem end if
  ) & rem next %%I
) & rem end if
endlocal & set /A LEN=%LEN%
if not "%~2" EQU "" set %~2=%LEN%
echo %LEN%
exit /B

<强>假设:

  • &#34; .exe&#34;部分仅在每行Exies.txt出现一次;
  • 文件名至少包含一个除\?*/:<>|";
  • 以外的字符
  • 文件名左侧分隔
    • 反斜杠\或冒号:(表示已指定路径),
    • 或双引号"(它可能已包含在一对中);