awk连接字符串直到包含子字符串

时间:2017-12-13 15:03:28

标签: regex bash awk

我有this示例中的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字时停止连接,因此所需的输出是:

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

5 个答案:

答案 0 :(得分:8)

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/ - 范围模式
  

范围模式由两个以逗号分隔的模式组成   表格‘begpat, endpat’。它用于匹配连续范围   输入记录。第一个模式begpat控制范围   开始,而endpat控制模式结束的位置。

  • /^end/? ORS:"," - 为范围内的当前项设置分隔符

答案 1 :(得分:4)

这是另一个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}

答案 2 :(得分:2)

您可以使用此fit_transform()

awk

答案 3 :(得分:2)

另一种方式,类似于How to select lines between two patterns?

中的答案
1
  • 这不需要缓冲区,但不会检查$ 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将ORS设置为/START/{ORS=","; f=1}并设置一个标志(控制要打印的行)
  • ,将ORS设置为结束条件的换行符。打印该行并清除标记 只要设置了此标志,
  • /end/{ORS=RS; print; f=0}就会打印输入记录

答案 4 :(得分:0)

由于我们似乎已经通过方法来实现这一目标,所以对于多字符RS,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