我有一个文本文件,其中包含由空行分隔的连续非空行块。我想将行连接到一个块中(类似于 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. 删除每行的前导和尾随空格(修剪)。