神秘的 awk 脚本连接行

神秘的 awk 脚本连接行

我有一个文本文件,其中包含由空行分隔的连续非空行块。我想将行连接到一个块中(类似于 vi 编辑器中的“J”键)。这里 我发现“cfajohnson”的以下脚本可以完成这项工作:

awk 'BEGIN { RS = ""; OFS = " "}
           {$1 = $1; print }'

所以处理文件

hello
    world

this
    is
  another
line

给出

hello world
this is another line

(在两台 Solaris 计算机(SunOS 5.11 11.1 和 SunOS 5.10 Generic_147440-16)上,当块被三个或更多空行分隔时,我会遇到分段错误。在 Linux 上,如果它们被两行或更多行分隔,它也可以工作)

来自 awk (Linux) 手册:

 Assigning a value to an existing field causes 
 the whole record to be rebuilt when $0 is referenced.
...
OFS         The output field separator, a space by default.
...
RS          The input record separator, by default a newline.

如果省略的话,该脚本似乎也可以工作

RS=" "

BEGIN 块中的语句(空白是 RS 的默认值) 我不明白为什么这个脚本会加入行,删除前导和尾随空白。

有人能解释一下这个脚本是如何工作的吗?

答案1

我认为您可以省略OFS=" ",但RS=""为了将 awk 放入,(或等效项)是必不可少的段落模式

从 GNUawk手册中,4.8 多行记录(其他 awk 的行为类似,据我所知):

另一种技术是用空行分隔记录。通过一种特殊的安排,RS 的值是空字符串,表示记录之间由一个或多个空行分隔。当 RS 设置为空字符串时,每个记录始终以遇到的第一个空行结束。直到后面的第一个非空行才开始下一条记录。无论一行中出现多少个空行,它们都充当一个记录分隔符。 (空白行必须完全为空;仅包含空格的行不算在内。)

在此模式下,默认情况下字段仍以空格分隔,但空格现在包含(单个)换行符。默认输出字段分隔符是单个空格,因此将每个多行记录转换为单行空格分隔字段所需的就是强制awk重建记录变量$0,这是作为赋值的副作用实现的$1=$1 - 请参阅例子著名的 awk 行话解释,第二部分:文本转换和替换,27. 删除每行的前导和尾随空格(修剪)。

相关内容