如何将除第一场比赛之外的所有匹配项与 sed 匹配



我正在使用某种模式在 Git 中执行提交消息,以简化新版本 (https://stackoverflow.com/a/5151123/520162) 的更改日志的创建。

应该纳入我的更改日志的每个更改都以 CHGNEWFIX 为前缀。

在生成我的更改日志时,我为每个修订版使用以下命令打印出我要解析的修订版:

git show --quiet --date=short --pretty=format:"%cd %an %s%n%n%w(100,21,21)%b%n" $CURRENTREVISION

主体(%s)持有修改的主体。

接下来,我使用 SED 修改生成的输出,以便它们符合我的更改日志文件的需求。

现在,碰巧在主题行中,多次出现 CHGNEWFIX 。我的主题输出如下所示:

DATE NAME FIX first change NEW second change CHG third change
我想在除

第一次出现的关键字之外的所有关键字前面加上换行符,以便每个CHGNEWFIX都开始一个新行:

DATE NAME FIX first change
          NEW second change
          CHG third change

为了实现这一目标,我必须告诉 SED 什么?

sed不是

最合适的工具

有了awk,它看起来像这样。

awk '{n=0; for (i=1; i<=NF; i++) {if ($i ~ /(NEW|FIX|CHG)/) {$i=(n++?"n          ":"")$i}}}7'
  • n=0(重新)设置标志
  • for (i=1; i<=NF; i++)遍历生产线的每个字段
  • if ($i ~ /(NEW|FIX|CHG)/)字段是否为标记之一
    • $i=(n++?"n ":"")$i通过添加适当的前导空格(或无)来更新字段
  • 7真实 y 模式打印出当前行。
awk '{while(++i<=NF){if($i~/FIX|NEW|CHG/){if(f){$i="n"$i}else{f=1}}}}1'

甚至更小:

awk '{while(++i<=NF){if($i~/FIX|NEW|CHG/){if(f++){$i="n"$i}}}}1'

例:

$echo "DATE CH NAME FIX first change NEW second change CHG third change" | awk '{while(++i<=NF){if($i~/FIX|NEW|CHG/){if(f){$i="n"$i}else{f=1}}}}1'
DATE CH NAME FIX first change 
NEW second change 
CHG third change

1st to last字段开始。 对于与 3 种模式中的任何一种匹配的字段,我们检查是否f=1 ,在第一个匹配的情况下,这将为 false。 由于我们正在做 f++ ,对于下一场比赛,它将是真的,因此"n"将被添加在前面。

sed '/^DATE NAME/ {
:cycle
   s/(.{1,}) (FIX .*)/1
2/g
   t cycle
   s/(.{1,}) (NEW .*)/1
2/g
   t cycle
   s/(.{1,}) (CHG .*)/1
2/g
   t cycle
   s/n/&          /g
   s/n */ /
   }' YourFile

类似于 posix 版本(在 GNU sed 上--posix)。

一个简单的

   s/(.{1,}) ((CHG|FIX|NEW) .*)/1
2/g
   t cycle

可以用允许|的 GNU sed 替换前 3 个s///

我用第一/^DATA NAME/作为过滤器保护了一点,但如果只处理这种线,就不需要这个(和相关{ }

sed听起来不像是这项工作的正确工具。 sed中保存的状态非常有限,您的目标需要一个计数器,这在sed中相当困难。 我想你以后不会乐意维护你的代码。

相反,我认为也许Perl是一个很棒的工具。

像这样:

while(<STDIN>){
    my @matches = m/^(.*?)((?:FIX|NEW|CHG).*?)*$/;
    my $date_name = unshift @matches; # only FIX, NEW, CHG remains now
    print $date_name, unshift @matches;
    while (@matches) { print "tt", unshift @matches; }
}

管道输入原始数据,然后重定向到外壳中的文件。

相关内容

  • 没有找到相关文章

最新更新