如何使用 awk 执行多行匹配和替换?

如何使用 awk 执行多行匹配和替换?

在文本文件中,忽略每行末尾的任何尾随空格,我假设如果一行不是以数字结尾,则该行和下一行之间有一个换行符,我想找到这些换行,然后将它们连接成一行。例如

line 1
li
ne 2

第二行和第三行之间有一个换行符,我应该将文件修改为

line 1
line 2

为了找到这样的换行符,我需要进行多行匹配。我通过更改记录分隔符来做到这一点,但以下不起作用:

$ awk 'BEGIN{RS="";}; { if (match($0, /[^[:digit:] ] *\n/)) print $0;} ' inputfile

要连接由换行符分隔的两行,我仍然想知道。

谢谢。

答案1

我会以不同的方式解决它:通过循环输入直到找到“行结束条件”:

awk '{ 
       line=$0; 
       while($0 !~ /[[:digit:]] *$/ && getline > 0) { 
         line=line$0; 
       }
       print line
     }' < input

在扩展输入文件上:

line 1
li
ne 2
li
ne 
number 3
line 4

或者,更详细地(查看尾随空格):

$ cat -e input
line 1$
li$
ne 2$
li$
ne $
number 3$
line 4$

输出是:

line 1
line 2
line number 3
line 4

答案2

你可以按照以下方式运行一些东西

awk 'BEGIN{RS=SUBSEP; ORS="" } {print gensub(/([^0-9])\n/,"\\1","g",$0)}' ex
  • RS=SUBSEP将寄存器分隔符设置为文本文件中从未出现的值(将输入文件设置为$0
  • 那么你最喜欢多行转换吗

答案3

$ cat file
line 1
li
ne 2
lo
ng li
ne 3
$ awk 'line ~ /[0-9]$/ { print line; line = "" } { line = line $0 } END { print line }' file
line 1
line 2
long line 3

这会在变量中累积一条“输出行” line,每当该变量以数字结尾时,就会打印并重置它。它还在最后打印以输出最后一行(无论是否完整)。

近似sed等效(但具有显式循环):

$ sed -e ':again' -e '/[0-9]$/{ p; d; }; N; s/\n//' -e 'tagain' file
line 1
line 2
long line 3

答案4

小 GNU sed

sed ':L; /[0-9] *$/!{N; bL;}; s/\n//g' file

相关内容