在Linux上,这按预期运行:
$ echo -e "line1\r\nline2"|awk -v RS="\r\n" '/^line/ {print "awk: "$0}'
awk: line1
awk: line2
但在windows下\ r \ n被删除(awk认为这一行):
视窗:
$ echo -e "line1\r\nline2"|awk -v RS="\r\n" '/^line/ {print "awk: "$0}'
awk: line1
line2
Windows GNU Awk 4.0.1 Linux GNU Awk 3.1.8
来自@EdMorton的编辑(对不起,如果这是一个不需要的补充,但我认为这可能有助于证明这个问题):
考虑这个RS设置和输入(在cygwin上):
$ awk 'BEGIN{printf "\"%s\"\n", RS}' | cat -v
"
"
$ echo -e "line1\r\nline2" | cat -v
line1^M
line2
这是带有gawk的Solaris:
$ echo -e "line1\r\nline2" | awk '1' | cat -v
line1^M
line2
这是ggk的cygwin:
$ echo -e "line1\r\nline2" | awk '1' | cat -v
line1
line2
RS
只是它的默认换行符所以控件-M在哪里进入cygwin?
答案 0 :(得分:7)
我刚刚与Arnold Robbins(gawk的提供者)进行了核实,答案是它是由C库完成的并且为了阻止它发生你应该将awk BINMODE变量设置为3:
$ echo -e "line1\r\nline2" | awk '1' | cat -v
line1
line2
$ echo -e "line1\r\nline2" | awk -v BINMODE=3 '1' | cat -v
line1^M
line2
如果感兴趣,请参阅手册页以获取更多信息。
答案 1 :(得分:4)
在Cygwin下,问题似乎是awk
我尝试了一些不同的东西,似乎awk
默默地在输入数据中用\r\n
替换\n
。
如果我们只是要求awk
重复未经修改的文字,它将"清理"马车返回时没有问:
$ echo -e "line1\r\nline2" | od -a
0000000 l i n e 1 cr nl l i n e 2 nl
0000015
$ echo -e "line1\r\nline2" | awk '{ print $0; }' | od -a
0000000 l i n e 1 nl l i n e 2 nl
0000014
但是,它会使其他回车保持不变:
$ echo -e "Test\rTesting\r\nTester\rTested" | awk '{ print $0; }' | od -a
0000000 T e s t cr T e s t i n g nl T e s
0000020 t e r cr T e s t e d nl
0000033
使用_
的自定义记录分隔符,最后使回车保持原样:
$ echo -e "Testing\r_Tested" | awk -v RS="_" '{ print $0; }' | od -a
0000000 T e s t i n g cr nl T e s t e d nl
0000020 nl
0000021
最有说服力的例子涉及在数据中使用\r\n
,但不能作为记录分隔符:
$ echo -e "Testing\r\nTested_Hello_World" | awk -v RS="_" '{ print $0; }' | od -a
0000000 T e s t i n g nl T e s t e d nl H
0000020 e l l o nl W o r l d nl nl
0000034
awk
在输入数据中盲目地将\r\n
转换为\n
,即使我们没有要求它。
这种替换似乎是在应用记录分离之前发生的,这解释了为什么RS="\r\n"
永远不匹配任何东西。当awk
正在寻找\r\n
时,它已经在输入数据中用\n
替换了它。