Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File Bat文件以在.txt文件中查找特定文本_File_Search_Batch File_Filter_Find - Fatal编程技术网

File Bat文件以在.txt文件中查找特定文本

File Bat文件以在.txt文件中查找特定文本,file,search,batch-file,filter,find,File,Search,Batch File,Filter,Find,只是想知道批处理文件中是否有任何代码可以在.txt文件中找到特定的文本或单词 例如: 那只敏捷的棕色狐狸跳过了那只懒狗 那只敏捷的棕色狐狸跳过了那只懒狗 那只敏捷的棕色狐狸跳过了那只懒狗 敏捷的棕色狐狸跳过了懒狗 那只敏捷的棕色狐狸跳过了那只懒狗 敏捷的棕色狐狸跳过了懒狗 那只敏捷的棕色狐狸跳过了那只懒狗 从上面的例子中可以看出,我想搜索“\mark{Number here}”单词,并且如果有可能出现相同的单词,例如第一行和第五行,它将只显示第一行的“\mark{1}”,而忽略第五行中的相同单词

只是想知道批处理文件中是否有任何代码可以在.txt文件中找到特定的文本或单词

例如:

  • 那只敏捷的棕色狐狸跳过了那只懒狗
  • 那只敏捷的棕色狐狸跳过了那只懒狗
  • 那只敏捷的棕色狐狸跳过了那只懒狗
  • 敏捷的棕色狐狸跳过了懒狗
  • 那只敏捷的棕色狐狸跳过了那只懒狗
  • 敏捷的棕色狐狸跳过了懒狗
  • 那只敏捷的棕色狐狸跳过了那只懒狗
  • 从上面的例子中可以看出,我想搜索“\mark{Number here}”单词,并且如果有可能出现相同的单词,例如第一行和第五行,它将只显示第一行的“\mark{1}”,而忽略第五行中的相同单词

    因此,结果将打印在一个txt文件中:

  • \标记{1}
  • \标记{10}
  • \标记{100}
  • \标记{1000}
  • \标记{30}

  • 如果您下载一个像sed for Windows(或者grep for Windows)这样的工具,这应该相对容易。Gnu项目免费提供sed和grep for Windows

    使用VBScript、JScript或powershell的正则表达式功能也应该相对容易

    但我想我会尝试使用本地批处理。FINDSTR支持原始正则表达式,但它无法提取匹配的文本,因此批处理解决方案相当复杂

    下面的解决方案可以在一行上找到多个标记。它还能够计算每个不同标记的出现次数。SET search and replace是不区分大小写的,所以我不得不使整个解决方案不区分大小写

    该解决方案只能处理长度小于等于8191字节的行

    即使对于非常大的文件,只要包含标记的行数相对较少,性能也应该很好

    @echo off
    setlocal disableDelayedExpansion
    set "file=test.txt"
    set LF=^
    
    
    ::The two blank lines above are critical to create linefeed - do not remove.
    
    ::Clear any existing \mark variables
    for /f "delims==" %%A in ('2^>nul set \mark{') do set "%%A="
    
    ::Find all lines that contain at least one valid mark and call a routine
    ::to parse out all marks
    for /f eol^=^%LF%%LF%delims^= %%A in (
      'findstr /ri \mark{[0-9][0-9]*} "%file%"'
    ) do (
      set "ln=%%A"
      call :parseMarks
    )
    
    ::Create file containing found marks only
    >marks.txt (
      for /f "delims==" %%A in ('set \mark{') do echo %%A
    )
    
    ::Create file containing found marks with counts
    >markCounts.txt set \mark{
    
    ::Print the results
    echo Here is a list of found marks
    echo -----------------------------
    type marks.txt
    echo(
    echo Here is a list of found marks with the counts
    echo ---------------------------------------------
    type markCounts.txt
    
    exit /b
    
    :parseMarks
    setlocal enableDelayedExpansion
    set "ln2=!ln:*\mark{=!"
    if !ln2! neq !ln! (
      for /f "tokens=1* delims=}" %%B in ("x!ln2!x") do (
        endlocal
        echo(%%B|findstr /xr x[0-9][0-9]* >nul && (
          for /f "delims=x" %%D in ("%%B") do set /a \mark{%%D}+=1
        )
        set "ln=%%C"
      )
      if defined ln goto :parseMarks
    )
    exit /b
    
    这是我使用的test.txt文件。它有许多问题测试用例,这使得批量解决方案变得困难

    The \mark{} quick brown fox jump \mark{1} over the lazy dog
    The quick \mark{10} brown fox jump over the \mark{99a} lazy dog
    The quick \mark{}99} brown fox jump over the lazy \mark{100} dog! \MARK{22}!
    The quick brown fox jump over the lazy dog \mark{1000} \mark{99
    ;The \mark{1} quick brown fox jump over the lazy dog
    The \mark{!!99} quick brown fox jump over the lazy dog \mark{100}
    \mark{22}The quick brown fox \mark{30} jump over the lazy dog
    exclude \mark{100a}
    exclude \mark{}
    include \MARK{22}
    
    这是我的结果

    Here is a list of found marks
    -----------------------------
    \mark{1000}
    \mark{100}
    \mark{10}
    \mark{1}
    \mark{22}
    \mark{30}
    
    Here is a list of found marks with the counts
    ---------------------------------------------
    \mark{1000}=1
    \mark{100}=2
    \mark{10}=1
    \mark{1}=2
    \mark{22}=3
    \mark{30}=1
    

    如果要在不使用非microsoft实用程序的情况下执行此操作,可以使用以下方法:

    注意:此方法使用dostips.com提供的strlen.bat例程


    你必须使用REGEX来实现这一点——你安装了powershell吗?嗨,我只是想说声谢谢,它真的解决了我的问题。非常感谢和尊重。现在,我可以做我的工作比只是手动搜索这个词更快。再次非常感谢。@Life'sAJoke-如果你觉得你的问题已经得到了回答,那么你应该点击答案左上角附近的复选标记来接受答案。这样做可以让其他人知道问题已经得到了回答,它会给你2分声誉,给回答者15分。只能接受一个答案。一旦你得到15分,你可以投票选出你认为有用的答案,包括对其他人问题的答案。每次向上投票都会给答题海报10分,但对你这个选民来说什么都没有。
    @echo off
    setlocal enabledelayedexpansion
    for /f "tokens=*" %%x in (findOnce.txt) do call :work "%%x"
    echo #%linenum% lines.
    endlocal
    goto :eof
    
    :work
    set line=%~1
    if not "!line:\mark{=!"=="!line!" (
      call strlen line len
      for /l %%y in (0,1,!len!) do (
        if "!line:~%%y,1!"=="\" (
          set clip= \
        ) else (
          if "!clip!" neq "" ( 
            set clip=!clip!!line:~%%y,1!
            if "!line:~%%y,1!"=="}" (
              call :getcheck "!markset!" "!clip!"
              if "!markset!"=="" (
                set /a linenum=!linenum! + 1
                set markset=!markset!!clip!
                echo !linenum! !clip!
                set clip=
              ) else if "!check!"=="!markset!" (
                set /a linenum=!linenum! + 1
                set markset=!markset!!clip!
                echo !linenum! !clip!
                set clip=
              )
            )
          )
        )
      )
    )
    goto :eof
    
    :getcheck
      set markset=%~1
      set clip=%~2
      call set check=%%markset:!clip!=%%
      if  "!check:~-1!"=="=" set check=!check:~,-1!
      if "!check:~1,1!"==" " set check=!check,~1!
    goto :eof