使用 sed,在匹配上方添加第 X 行

使用 sed,在匹配上方添加第 X 行

我知道要添加/添加某些内容,我只需要做:

sed -i '/pattern/a new thing!'

但是,我想匹配一行,并在前面添加两行以上的内容。

我想将工具仅限于 ubuntu 12.04 中开箱即用的工具,我不知道是否awk符合要求。

以防万一我在寻求问题 B 的解决方案时需要解决问题 A: .m3u8 文件的摘录如下所示:

#EXTINF:4.304300,
output-000.ts
#EXTINF:5.705700,
output-001.ts
#EXTINF:4.304300,
output-002.ts
#EXTINF:5.705700,
output-003.ts

现在,我的目标是在每个 X'th 之前插入一行 2 行output-XXX.ts。例如我想实现这个:

#Inserted line 0
#EXTINF:4.304300,
output-000.ts
#EXTINF:5.705700,
output-001.ts
#Inserted line 1
#EXTINF:4.304300,
output-002.ts
#EXTINF:5.705700,
output-003.ts

答案1

使用awk(默认安装在 POSIX 系统上,包括 ubuntu):

POSIXLY_CORRECT=1 awk -v X=2 '
  NR >= 2 && /^output-[0-9]{3}\.ts$/ && ++n % X == 1 {
    print "#Inserted line", i++
  }
  NR>1 {print last}
  {last = $0}
  END{if (NR) print last}' < file.in > file.out

这是上面 2 行的内容。概括为上面的 N 行:

POSIXLY_CORRECT=1 awk -v N=2 -v X=2 '
  BEGIN{N--}
  NR > N {
    if (/^output-[0-9]{3}\.ts$/ && ++n % X == 1)
      print "#Inserted line", i++
    print l[NR % N]
  }
  {l[NR % N] = $0}
  END{
    for (i = NR > N ? NR - N + 1 : 1; i <= NR; i++) print l[i % N]
  }'

答案2

Perl 来拯救:

< .m3u8  perl -ne 'push @w, $_;
                   unshift @w, "#Inserted line " . (0 + $c++) . "\n"
                       if /^output-[0-9]+\.ts/ && 0 == $m++ % 2;
                   print shift @w while @w > 1;
                   }{ print @w;'

@w是保留最后两行的“滑动窗口”数组。$m包含匹配的数量,即到目前为止遇到的“output-XXXX”行的数量,因此如果模 2 给出 0,则您将拾取每第二个匹配。unshift在窗口数组的开头插入一行,然后shift检索它。最后,您必须输出剩余的行。

相关内容