Sed 命令在找到模式时去除模式并将其添加到方块 [] 到后续行之间,直到找到新模式

Sed command to strip pattern when found and add it between square [] to following lines until new one is found

这是我的起点。

#CHECK THISOUT
------EXAMPLE 1------ ; http://www.idontneed.com
Google ; http://www.google.com
Yahoo ; http://www.yahoo.com
------EXAMPLE 2------ ; http://idontcare.com
Ebay ; http://www.ebay.com
Amazon ; http://www.amazon.com

要匹配的模式是带有 ------SOMETHING------

的字符串

期望的输出是:

#CHECK THISOUT
[------EXAMPLE 1------]  Google ; http://www.google.com
[------EXAMPLE 1------]  Yahoo ; http://www.yahoo.com
[------EXAMPLE 2------]  Ebay ; http://www.ebay.com
[------EXAMPLE 2------]  Amazon ; http://www.amazon.com

Perl 来拯救!

perl -ne 'if (/^(------.*------) ;.*/) { $h =  }
          elsif ($h) { print "[$h]  $_" }
          else {print}' < input > output
  • -n逐行读取输入
  • 如果一行包含模式,它将存储在 $h 变量中
  • 如果模式不存在,但之前已设置,则打印时附加行
  • 否则,打印该行(在满足任何模式之前打印第一行)

sed 中非常简单:

sed -e '/^------..*------/,$ {
         /^\(------..*------\).*/ { s//[]/; h; d; }
         G; s/\(.*\)\n\(\[.*\]\)/ /
        }' data

解释:

  • 直到找到触发模式,才能正常打印线条;该脚本仅从找到第一个模式时起更改任何内容。然后脚本的其余部分运行。
  • 如果线是触发模式,捕获模式并将其括在方括号中 (s/…/…/)。
  • 将模式复制到保留 space (h)。
  • 删除该行并移至下一行。
  • 这是一条没有触发模式的线。
  • 将保留 space 的内容附加到换行符 (G) 之后的模式 space。
  • 将模式 space 拆分为 'before the newline' 和 'after the newline' 并在 (s/…/…/).
  • 之间使用 space 重新排序
  • 让普通的'print at the end of the cycle'打印结果

如果您想要两个 space 而不是方括号和其余部分之间的一个,请在第二个 s/…/…/.

中添加一个额外的 space

示例输出:

#CHECK THISOUT
[------EXAMPLE 1------] Google ; http://www.google.com
[------EXAMPLE 1------] Yahoo ; http://www.yahoo.com
[------EXAMPLE 2------] Ebay ; http://www.ebay.com
[------EXAMPLE 2------] Amazon ; http://www.amazon.com

awk解法,类似。使用 ; 作为字段分隔符,所以有一个额外的 space

$ cat ip.txt 
#CHECK THISOUT
------EXAMPLE 1------ ; http://www.idontneed.com
Google ; http://www.google.com
Yahoo ; http://www.yahoo.com
------EXAMPLE 2------ ; http://idontcare.com
Ebay ; http://www.ebay.com
Amazon ; http://www.amazon.com

$ awk -F';' '{ if(/^------.*------/){ h =  } else if(h){ print "[" h "] " [=10=] } else {print} }' ip.txt
#CHECK THISOUT
[------EXAMPLE 1------ ] Google ; http://www.google.com
[------EXAMPLE 1------ ] Yahoo ; http://www.yahoo.com
[------EXAMPLE 2------ ] Ebay ; http://www.ebay.com
[------EXAMPLE 2------ ] Amazon ; http://www.amazon.com

sed 用于在单行上进行简单替换,仅此而已。对于其他任何事情,您应该使用 awk 以获得清晰度、可移植性、效率、简单性、可增强性、健壮性等:

awk 'match([=10=],/-{5}.+-{5}/,a){ v="["a[0]"]  "; next } {print v [=10=]}' file
#CHECK THISOUT
[------EXAMPLE 1------]  Google ; http://www.google.com
[------EXAMPLE 1------]  Yahoo ; http://www.yahoo.com
[------EXAMPLE 2------]  Ebay ; http://www.ebay.com
[------EXAMPLE 2------]  Amazon ; http://www.amazon.com

以上使用 GNU awk 作为第三个参数来匹配 (),与其他 awks 它将是:

$ awk 'match([=11=],/-{5}.+-{5}/){ v="["substr([=11=],RSTART,RLENGTH)"]  "; next } {print v [=11=]}' file
#CHECK THISOUT
[------EXAMPLE 1------]  Google ; http://www.google.com
[------EXAMPLE 1------]  Yahoo ; http://www.yahoo.com
[------EXAMPLE 2------]  Ebay ; http://www.ebay.com
[------EXAMPLE 2------]  Amazon ; http://www.amazon.com