正则表达式 - 在第一次匹配后追加

regex - append after first match

假设我有以下类型的文件:

a a c
b b c
c c c
d d c
e e c
a a c
b b c
c c c
d d c
e e c

我如何结束:

a a c
b b c
c c c
—————
d d c
e e c
a a c
b b c
c c c
d d c
e e c

...不只是在第 3 行之后添加 em dashes(第一行带有 c c c)。

这个 awk 可以工作:

awk '1; !flag && /c c c/ { flag = 1; print "—————" }' filename

即:

1                   # first, print every line (1 meaning true here, so the
                    # default action -- printing -- is performed on all
                    # lines)
!flag && /c c c/ {  # if the flag is not yet set and the line we just printed
                    # matches the pattern:
  flag = 1          # set the flag
  print "—————"     # print the dashes.
}

或者使用 sed(尽管我建议使用 awk 解决方案):

sed -n 'p; /c c c/ { x; /^$/ { s//—————/; p }; x }' filename

这有点复杂。知道一开始hold buffer是空的:

p             # print the line
/c c c/ {     # if it matches the pattern:
  x           # exchange hold buffer and pattern space
  /^$/ {      # if the pattern space (that used to be the hold buffer) is
              # empty:
    s//—————/ # replace it with the dashes
    p         # print them
  }
  x           # and exchange again. The hold buffer is now no longer empty,
              # and the dash block will not be executed again.
}
sed '/c c c/!b
s/$/\
-----/
# Using buffer
:cycle
N
$!b cycle' YourFile
  • 直到第一个c c c,只打印行
  • 在线添加一行(所以在第一个 ccc)
  • 在缓冲区中加载一行(不打印)
  • 循环加载直到最后一行
  • 最后一行打印整个(通过退出循环,而不是像新的 N 循环那样的动作)

或通过使用小缓冲来替代大文件

# without big buffer
:cycle
n
s/.*\n//
$!b cycle' YourFile
  • 打印第一行并加载新行
  • 删除第一行
  • 循环不结束