为什么`awk 1 RS =,<<< " 1,2"`写一个额外的新行?

时间:2016-09-16 14:39:09

标签: awk gawk

answered一个问题,我使用了一些awk技巧将逗号转换为新行:

awk 1 RS=, file

但是,我注意到这会在输出结尾引入一条额外的新行:

$ cat a
1,2
$ awk 1 RS=, a
1
2
             # one extra line
$ awk 1 RS=, <<< "1,2"
1
2
             # one extra line

由于1{print $0}的简称,我决定看看发生了什么:

$ awk '{print $0, "hey"}' RS=, <<< "1,2"
1 hey
2
 hey

所以是的,显然分裂完成了,但由于某种原因,第二条记录包含2后跟一条新行。是的,awk只看到两条记录:

$ awk '{print NR}' RS=, <<< "1,2"
1
2

对我来说这是有道理的,因为echo和here-strings在输出的末尾添加了这样的新行,而printf却没有。并且它有效地与 printf

一起使用
$ awk '{print $0, "hey"}' RS=, < <(printf "1,2")
1 hey
2 hey         # no more lines after this

好的,我说:那么新行上的问题只会附加到字符串的末尾。

但是......我发现并非总是如此,我的困惑变得更大了:

$ awk '{print $0, "hey"}' <<< "1,2"
1,2 hey         # no more lines after this

所以我的问题是: RS=,做什么导致额外的新行被追加?

3 个答案:

答案 0 :(得分:2)

它是输入流中的换行符。

$ awk 1 RS=, < <(echo -n 1,2)

1
2

在输出中没有额外的换行符。但是,执行此操作的标准方法是使用tr

$ tr ',' '\n' < file

比较

$ echo 1,2 | awk 1 RS=,
1
2

$ echo 1,2 | tr ',' '\n'
1
2

答案 1 :(得分:2)

Awk处理每条记录,自动从末尾删除记录分隔符。如果您已将其更改为换行符之外的其他内容,则表示它不会被删除,因此您最终会遇到此行为。

你的记录数&#34;即使你只有一个,,它也是2,但在这个例子中它也是2(希望它不会让这更令人困惑!):

$ printf 'a\nb' | awk '{print NR}'
1
2

答案 2 :(得分:1)

添加换行符不是awk,它是<<<。如果shell没有使用<<<在您指定的文本末尾添加终止换行符,则结果将不是每个POSIX的文本“文件”,因此将依赖于任何试图解析的工具的未定义行为它

因此,当您撰写command <<< 'foo'时,command看到的内容不是foo,而是foo\n,因此在您的命令行中:

awk 1 RS=, <<< "1,2"

awk看到的是1,2\n,当您将其分成,的记录时,您会获得1的第一条记录和2\n的第二条记录。