Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.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
Regex 打印文件至第n个匹配项_Regex_Bash_Sed_Awk - Fatal编程技术网

Regex 打印文件至第n个匹配项

Regex 打印文件至第n个匹配项,regex,bash,sed,awk,Regex,Bash,Sed,Awk,我正试着把一个文件分开sed来执行此操作 sed -e '0,/expr/d' filename 将在“expr”之后给出文件的下半部分,但如果出现多个事件,并且我希望在第n个事件之后拆分,该怎么办?我想在第二次发生后我是否想要它 sed -e '0,/expr/! {/expr/,$d}' filename 给出文件的上半部分,直到第二个匹配的“expr”。感叹号(!)告诉它忽略第一个范围,只将大括号中的命令应用于文件的其他部分 但更一般的情况又如何呢?例如,从最后一次出现的第二次开始 我

我正试着把一个文件分开<例如,可以使用code>sed来执行此操作

sed -e '0,/expr/d' filename
将在“expr”之后给出文件的下半部分,但如果出现多个事件,并且我希望在第n个事件之后拆分,该怎么办?我想在第二次发生后我是否想要它

sed -e '0,/expr/! {/expr/,$d}' filename
给出文件的上半部分,直到第二个匹配的“expr”。感叹号(!)告诉它忽略第一个范围,只将大括号中的命令应用于文件的其他部分

但更一般的情况又如何呢?例如,从最后一次出现的第二次开始

我一直在这里使用
sed
,但我认为
awk
也会有优雅的解决方案

简单的awk解决方案:

  • 小于或等于
    /regex/
    第次匹配的
    $n

    awk-vn=$n'{print}/regex/&&--n{exit}'

  • 最多但不包括第次匹配的
    $n

    awk-vn=$n'/regex/&&--n{exit}{print}'

    在上述两种程序中,将n设置为0将打印整个文件。另外,
    {print}
    的两种用法都可以更改为
    1{print}
    。(或仅在第二个程序中
    1

    完整性:

  • $n
    第次匹配后的所有内容:


    awk-vn=$n'n除了@rici的解决方案之外,还有一些
    awk
    的变体

  • 不超过并包括第次匹配的
    $n

    awk-vn=$n'p=n'文件

  • 来自且不包括第次匹配的
    $n

    awk-vn=$n'p>=n/regex/{p++}文件


  • 但更一般的情况又如何呢?例如,从第二个到最后一个 发生

    在这种情况下,简单的方法是使用
    tac
    反向读取文件,执行上述选项并再次反向打印

  • 来自并包括上次匹配的
    $n

    tac文件| awk-vn=$n'p=n'| tac

  • 最后一次匹配之前(不包括)
    $n

    tac文件| awk-vn=$n'p>=n/regex/{p++}'| tac


  • OS X用户注意事项正如@mklement0在评论中指出的那样

    • 可怜的[stock]OSX用户(从OSX10.9开始)运气不佳:那里没有
      tac

    • 在OSX上,您可以使用
      tail-r
      (注意,Linux上的
      tail
      似乎不支持
      -r

    这可能适合您(GNU-sed):

    这将在第二次匹配
    REGEXP
    后打印任何内容


    注意:
    REGEXP
    每行可能出现一次或多次,但只计算一次。

    Great;如果将
    -vn=$n
    重新格式化为
    -vn=$n
    ,它也可以在OS X上使用。@mklement0:您在哪个版本的OS X上使用哪个版本的awk?
    -vn=$n
    语法适用于我尝试过的每个awk,包括我认为OSX使用的BSD awk。它是
    awk版本20070501
    (OSX 10.9)-奇怪,但这就是
    awk--version
    报告的内容。@mklement0:对于一个闪亮的新操作系统来说,这是一个令人惊讶的旧版本。解析-v选项的错误显然在2010年5月23日的版本中得到了修复;请参见此处的变更列表:是的,不幸的是,OSX附带的许多OSS组件都非常旧(另一个例子:bash版本是
    bash 3.2.51
    )——我认为,至少部分原因是政治(许可问题)。感谢您的更新。可怜的[stock]OS X用户(从OS X 10.9开始)运气不佳:没有
    tac
    。@mklement0我不熟悉OS X,只使用过Linux或Windows。那么,如何反转文件内容呢?感谢您启发我查找:在OS X上,您可以使用
    tail-r
    (请注意,Linux上的
    tail
    似乎不支持
    -r
    )。@mklement0感谢您的评论。我已经为任何OSX用户将它们添加到ans中。
    sed -nr 'x;/^X{2}/{x;p;b};x;/REGEXP/{x;s/^/X/;x}' file