Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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
Batch file 使用Windows批处理脚本匹配字符串后显示N行_Batch File_Append - Fatal编程技术网

Batch file 使用Windows批处理脚本匹配字符串后显示N行

Batch file 使用Windows批处理脚本匹配字符串后显示N行,batch-file,append,Batch File,Append,在Linux中,我们可以在匹配字符串后轻松显示N行,例如: grep-100“字符串”文件1>file2 Windows批处理脚本编写中的等效命令是什么?Windows批处理功能不多。您必须求助于功能强大的基于.Net的PowerShell 我希望您注意到,LinuxShell提供了一个优秀的基础设施,但是如果没有您刚才提到的许多支持应用程序(如grep),它将无能为力 您的问题的答案是使用带-Context选项的PowerShell sls命令:请参阅 批处理并不是为了达到这样的目的,但可以

在Linux中,我们可以在匹配字符串后轻松显示N行,例如:

grep-100“字符串”文件1>file2


Windows批处理脚本编写中的等效命令是什么?

Windows批处理功能不多。您必须求助于功能强大的基于.Net的PowerShell

我希望您注意到,LinuxShell提供了一个优秀的基础设施,但是如果没有您刚才提到的许多支持应用程序(如grep),它将无能为力

您的问题的答案是使用带-Context选项的PowerShell sls命令:请参阅


批处理并不是为了达到这样的目的,但可以通过劝说来完成这项工作

下面是一个演示:

@ECHO关闭
SETLOCAL
::查找各个部分
调用q29044669s“100lines.txt”“line45”6
回音======================================
调用q29044669s“100lines.txt”“line21”16
回音======================================
调用q29044669s“100lines.txt”“line11”4
回音======================================
后藤:eof
这仅调用实际执行作业的批处理3次,在文件
100lines.txt
中查找字符串
line45/21/11
,并复制下面的6/16/4行

100lines.txt
只是一个测试文件

line1
line2
等等

下面是实际执行此任务的批处理:

q29044669S.bat

:::
:::ShowContext.bat  <Search>  <LeadingLines>  <TrailingLines>  [/option [val]]...
:::
:::  Write the context of lines matching a regular expression search string.
:::  The default reads input from stdin and writes output to stdout
:::
:::    <Search>         The regular expression search string
:::
:::    <LeadingLines>   Number of lines written prior to a matching line
:::
:::    <TrailingLines>  Number of lines written after a matching line
:::
:::  Options:
:::
:::    /I               Case-Insensitive search
:::
:::    /X               Enable use of \q (double quote) within <Search>
:::
:::    /OFF <MinWidth>  Prefix each context with the byte offset. The offset
:::                     is zero prefixed to a minimum width of <MinWidth>.
:::                     A <MinWidth> of 0 disables the option.
:::
:::    /S  <InVar>      Read input from variable <InVar>
:::
:::    /F  <InFile>     Read input from file <InFile>
:::
:::    /O  <OutFile>    Write output to file <OutFile>.
:::                     If <OutFile> is - then overwrite <InFile>
:::
:::ShowContext  /?      Prints this documentation
:::
::::
::::This script requires JREPL.BAT to function.
::::JREPL.BAT is available at http://www.dostips.com/forum/viewtopic.php?f=3&t=6044
::::
::::JREPL.BAT must be in one of the following locations:
::::  - the current directory
::::  - the same folder as this script
::::  - any of the folders within PATH
::::

@echo off
setlocal

:: Locate JREPL.BAT
if exist "jrepl.bat" (
  set "jrepl=jrepl.bat"
) else if exist "%~dp0jrepl.bat" (
  set "jrepl=%~dp0jrepl.bat"
) else for %%F in (jrepl.bat) do set "jrepl=%%~$path:F"
if not defined jrepl (
  for /f "tokens=* delims=:" %%A in ('findstr "^::::" "%~f0"') do echo(%%A
  exit /b 2
)>&2

:: Show help
if "%~1" == "/?" if "%~2" equ "" (
  for /f "tokens=* delims=:" %%A in ('findstr "^:::$ ^:::[^:]" "%~f0"') do echo(%%A
  exit /b 0
)

:: Load required arguments
set "search=%~1"
if not defined search goto :error
set /a "before=%~2, after=%~3" || goto :error
shift /1
shift /1
shift /1

:: Clear ERRORLEVEL
(call )

:: Do the work via JREPL.BAT
call "%jrepl%" "^(?:(?:(?:.(?!%search%))*\n){0,%before%}(?:.*(?:%search%).*\n?)(?:(?:.(?!%search%))*\n?){0,%after%})+" "$0+'--'" /jmatch /m %1 %2 %3 %4 %5 %6 %7 %8
if errorlevel 2 goto :error
exit /b %errorlevel%

:error
>&2 echo(
>&2 echo ERROR: Invalid or Insufficient arguments. Use ShowContext /? to see usage.
exit /b 2
@ECHO关闭
SETLOCAL ENABLEDELAYEDEXPANSION
::在文件%1中找到%2后重新生成%3行
设置“计数=”
对于/f“usebackqdelims=“%”中的%%a(“%~1”)DO(
如果定义了计数(
回声(%%a
设置/a计数+=1
如果!计数!geq%3转到:EOF
)否则(
回声(%%a | FIND/i“%~2”>NUL
如果不是错误级别1设置/a计数=0
REM如果要输出找到目标的行,请从下一行删除REM
REM回波(%%a
)
)
后藤:EOF
其中,
find
命令上的
/i
使匹配不区分大小写

它确保首先清除
count
,然后将文件的每一行应用于
%%a
(注意将跳过空行)当找到目标行时,
count
初始化为0,然后复制以下行并每次增加
count
。当达到限制时,批退出,结束本地环境,恢复
count
的初始值(如果已设置)

您可以通过以下命令行执行此操作:

q29044669s "100lines.txt" "line45" 6
但由于它是一个批处理文件,因此需要像在演示中一样从批处理中调用它

请注意,只有当文件名/目标字符串包含分隔符(如空格或逗号)时,才严格要求使用引号否则可能会被忽略。批处理名称并不重要-可以随意调用。

My可以轻松做到这一点。JREPL.BAT是一个混合JScript/batch实用程序,它对文本执行正则表达式替换。它是纯脚本,从XP开始在任何Windows计算机上本机运行

下面是一种使用用户提供的JScript的方法:

jrepl "search" "cnt=101;$0" /j /a /jbeg "cnt=0" /jendln "if (cnt) {output.writeLine($txt); if (!--cnt) output.writeLine('--');}" /f file1 /o file2
上述方法很有效,因为只要每行小于2GB,它就可以处理任何大小的文件。您可以添加
/I
选项以使搜索不区分大小写,并且
/L
选项将搜索视为字符串文字。您可以添加
/X
选项以允许转义序列,即使
/L
选项使用

也可以使用纯正则表达式求解:

@echo off
setlocal
set "search=search"
set "before=0"
set "after=100"
call jrepl "^(?:(?:(?:.(?!%search%))*\n){0,%before%}(?:.*(?:%search%).*\n?)(?:(?:.(?!%search%))*\n?){0,%after%})+" "$0+'--'" /jmatch /m /f file1 /o file2 
此正则表达式解决方案的优点是它支持前导和尾随上下文。缺点是整个输入文件必须加载到内存中,因此其总大小限制在2GB以下。此外,它不支持文本选项,因此必须手动转义任何正则表达式元字符

我已经将正则表达式解决方案合并到一个名为ShowContext.bat的新实用程序脚本中。所有工作都是通过上面的相同调用完成的。大部分代码都是文档、参数解析/验证和错误处理

ShowContext.bat

:::
:::ShowContext.bat  <Search>  <LeadingLines>  <TrailingLines>  [/option [val]]...
:::
:::  Write the context of lines matching a regular expression search string.
:::  The default reads input from stdin and writes output to stdout
:::
:::    <Search>         The regular expression search string
:::
:::    <LeadingLines>   Number of lines written prior to a matching line
:::
:::    <TrailingLines>  Number of lines written after a matching line
:::
:::  Options:
:::
:::    /I               Case-Insensitive search
:::
:::    /X               Enable use of \q (double quote) within <Search>
:::
:::    /OFF <MinWidth>  Prefix each context with the byte offset. The offset
:::                     is zero prefixed to a minimum width of <MinWidth>.
:::                     A <MinWidth> of 0 disables the option.
:::
:::    /S  <InVar>      Read input from variable <InVar>
:::
:::    /F  <InFile>     Read input from file <InFile>
:::
:::    /O  <OutFile>    Write output to file <OutFile>.
:::                     If <OutFile> is - then overwrite <InFile>
:::
:::ShowContext  /?      Prints this documentation
:::
::::
::::This script requires JREPL.BAT to function.
::::JREPL.BAT is available at http://www.dostips.com/forum/viewtopic.php?f=3&t=6044
::::
::::JREPL.BAT must be in one of the following locations:
::::  - the current directory
::::  - the same folder as this script
::::  - any of the folders within PATH
::::

@echo off
setlocal

:: Locate JREPL.BAT
if exist "jrepl.bat" (
  set "jrepl=jrepl.bat"
) else if exist "%~dp0jrepl.bat" (
  set "jrepl=%~dp0jrepl.bat"
) else for %%F in (jrepl.bat) do set "jrepl=%%~$path:F"
if not defined jrepl (
  for /f "tokens=* delims=:" %%A in ('findstr "^::::" "%~f0"') do echo(%%A
  exit /b 2
)>&2

:: Show help
if "%~1" == "/?" if "%~2" equ "" (
  for /f "tokens=* delims=:" %%A in ('findstr "^:::$ ^:::[^:]" "%~f0"') do echo(%%A
  exit /b 0
)

:: Load required arguments
set "search=%~1"
if not defined search goto :error
set /a "before=%~2, after=%~3" || goto :error
shift /1
shift /1
shift /1

:: Clear ERRORLEVEL
(call )

:: Do the work via JREPL.BAT
call "%jrepl%" "^(?:(?:(?:.(?!%search%))*\n){0,%before%}(?:.*(?:%search%).*\n?)(?:(?:.(?!%search%))*\n?){0,%after%})+" "$0+'--'" /jmatch /m %1 %2 %3 %4 %5 %6 %7 %8
if errorlevel 2 goto :error
exit /b %errorlevel%

:error
>&2 echo(
>&2 echo ERROR: Invalid or Insufficient arguments. Use ShowContext /? to see usage.
exit /b 2