尴尬的连接串直到包含子字符串



我有一个来自此示例的 awk脚本:

awk '/START/{if (x) print x; x="";}{x=(!x)?$0:x","$0;}END{print x;}' file

这是一个带有行的示例文件:

$ cat file
START
1
2
3
4
5
end
6
7
START
1
2
3
end
5
6
7

所以我需要停止在目标字符串包含 end Word时停止连接,因此所需的输出为:

START,1,2,3,4,5,end
START,1,2,3,end

Awk 解决方案(尽管它将两次检查/end/模式):

awk '/START/,/end/{ printf "%s%s",$0,(/^end/? ORS:",") }' file

输出:

START,1,2,3,4,5,end
START,1,2,3,end

  • /START/,/end/- range 模式

a 范围模式由两种图案制成 表格‘begpat, endpat’。它用于匹配连续的范围 输入记录。第一个模式begpat控制范围的位置 开始,当endpat控制模式结束的位置。

  • /^end/? ORS:","-设置范围内当前项目的定界符

这是另一个awk

$ awk '/START/{ORS=","} /end/ && ORS=RS; ORS!=RS' file
START,1,2,3,4,5,end
START,1,2,3,end

请注意,/end/ && ORS=RS;缩短了/end/{ORS=RS; print}

的形式

您可以使用此awk

awk '/START/{p=1; x=""} p{x = x (x=="" ? "" : ",") $0} /end/{if (x) print x; p=0}' file
START,1,2,3,4,5,end
START,1,2,3,end

另一种方式,类似于如何在两个模式之间选择行的答案?

$ awk '/START/{ORS=","; f=1} /end/{ORS=RS; print; f=0} f' ip.txt
START,1,2,3,4,5,end
START,1,2,3,end
  • 这不需要缓冲区,但不检查START是否具有相应的end
  • /START/{ORS=","; f=1}将ORS设置为,,并设置标志(控制要打印的行)
  • /end/{ORS=RS; print; f=0}在结束条件下将ORS设置为newline。打印行并清除标志
  • f打印输入记录只要设置此标志

,因为我们似乎已经沿着兔子洞走了下来的方法,所以对于Multi-Char RS,RT,RT和Gensub(),GNU Awk是一种相当合理的方法:

$ awk -v RS='end' -v OFS=',' 'RT{$0=gensub(/.*(START)/,"\1",1); $NF=$NF OFS RT; print}' file
START,1,2,3,4,5,end
START,1,2,3,end

相关内容

  • 没有找到相关文章

最新更新