Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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 如果在结束模式之前找到两个开始模式,如何停止sed脚本?_Regex_Bash_Shell_Svn_Sed_Perl - Fatal编程技术网

Regex 如果在结束模式之前找到两个开始模式,如何停止sed脚本?

Regex 如果在结束模式之前找到两个开始模式,如何停止sed脚本?,regex,bash,shell,svn,sed,perl,Regex,Bash,Shell,Svn,Sed,Perl,我需要在subversion转储中查找对pom.xml有更改的所有修订 我正在使用成功打印修订,然后使用sed筛选这些结果 我能够匹配版本号作为开始,但是如果我在找到停止之前找到第二个匹配的开始,我需要能够丢弃它 下面是我正在使用的命令: svnDumpTool=~/path/to/svndumptool.py target=specificSvn.dump # use svndumptool to read the svnlog from target to stdi

我需要在subversion转储中查找对pom.xml有更改的所有修订

我正在使用成功打印修订,然后使用sed筛选这些结果

我能够匹配版本号作为开始,但是如果我在找到停止之前找到第二个匹配的开始,我需要能够丢弃它

下面是我正在使用的命令:

    svnDumpTool=~/path/to/svndumptool.py
    target=specificSvn.dump

    # use svndumptool to read the svnlog from target to stdin | 
    # sed then matches start -r[0-9], such as -r103, ends on pom.xml
    # then redirects stdout > to a log file for this target

    $svnDumpTool log $target -v | sed -n '/r[0-9]/,/pom.xml/p' > $target.log
考虑这样的日志:

    -r0 | ... | ...
    Changed paths:
    none; initialization of the repo; not my match
    -r1 | ... | ...
    Changed paths:
    ... not my matches here
    --------
    -r2 | ... | ...
    Changed paths:
    ... nor here
    --------
    -r3 | ... | ...
    Changed paths:
    pom.xml
    --------
    -r4 | ... | ...
    Changed paths:
    pom.xml
    --------
    -r5 | ... | ...
    Changed paths:
    ... changes may or may not be here
    --------
以下是结果

  • 第一次通过时,我得到的比我想要的更多:

    • 我将在-r0开始时进行比赛
    • pom.xml结尾处的匹配来自-r3
    • 它从开始到停止打印所有内容,包括-r0、-r1和-r2:

      -r0 | ... | ...
      Changed paths:
      none; initialization of the repo; not my match
      -r1 | ... | ...
      Changed paths:
      ... not my matches here
      --------
      -r2 | ... | ...
      Changed paths:
      ... nor here
      --------
      -r3 | ... | ...
      Changed paths:
      pom.xml
      
  • 在第二关,我得到了我想要的东西:

    • 我会在-r4开始时进行一场比赛
    • pom.xml结尾处的匹配来自-r4:

      -r4 | ... | ...
      Changed paths:
      pom.xml
      
  • 因此,我认为我需要做的是:

  • 如果我找到一个开始
  • 在找到表达式匹配的结尾之前,我找到了另一个表达式匹配的开始
  • 然后扔掉第一个开始;否则打印
  • 我想我可能有答案,但我尝试过的任何尝试都失败了

    编辑:自动更正得到了我,我错误地将输出列为“Pom.xml”,而它应该是“Pom.xml”。

    我将用于这种情况:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my $svnDumpTool = '~/path/to/svndumptool.py';
    my $target      = 'specificSvn.dump';
    
    my @rev = split /----*/, `$svnDumpTool log $target -v`;
    foreach (@rev) {
      print if m/-r\d+[\s\S]*?Pom\.xml/;
    }
    

    Sed在这里是错误的工具。您可以这样做(sed是图灵完成的),但它将是不可读的

    Awk可能工作得更好。我不熟悉
    svndumtool
    ;假设它将分隔符
    -----------
    放在修订之间,则可以将其用作记录分隔符。GNU awk允许正则表达式作为记录分隔符

    awk -v RS='--------\n' -v ORS='--------\n' '
      /^pom\.xml$/ { print }
    '
    
    这可能适用于您(GNU-sed):


    这将存储以
    -r[0-9]
    开头的行以及保留空间中随后的行,用较新的行覆盖HS中已经存在的行,直到打印出包含
    Pom.xml
    的行为止。

    感谢同事推荐的awk;这个脚本比sed更容易阅读,因为它只是一个带有几个awk命令的基本正则表达式。我还喜欢破折号分隔符上的拆分,聪明!这很有效;它按照我的想法运行,并为awk脚本提供了类似的输出。
    sed '/-r[0-9]/{h;d};H;/Pom.xml/!d;x' file