在Linux上,这按预期运行:
$ echo -e "line1\r\nline2"|awk -v RS="\r\n" '/^line/ {print "awk: "$0}' awk: line1 awk: line2
但在Windows下,\ r被删除(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(对不起,如果这是一个不必要的补充,但我想也许这有助于certificate这个问题):
考虑这个RS设置和input(在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
这是cygwin与gawk:
$ echo -e "line1\r\nline2" | awk '1' | cat -v line1 line2
RS
只是它的默认换行符,所以控制-M进入cygwin的位置在哪里?
我刚刚与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
如果感兴趣,请参阅手册页获取更多信息。
在Cygwin下,这个问题似乎是awk
特有的。
我尝试了一些不同的东西, awk
在输入数据中似乎默默地用\r\n
替换\r\n
。
如果我们简单地要求awk
重复未经修改的文本,它将“回收”回车而不询问:
$ echo -e "line1\r\nline2" | od -a 0000000 line 1 cr nl line 2 nl 0000015 $ echo -e "line1\r\nline2" | awk '{ print $0; }' | od -a 0000000 line 1 nl line 2 nl 0000014
但是,它将保持其他回车完好:
$ echo -e "Test\rTesting\r\nTester\rTested" | awk '{ print $0; }' | od -a 0000000 T est cr T esting nl T es 0000020 ter cr T ested nl 0000033
使用_
的自定义记录分隔符结束离开回车完整:
$ echo -e "Testing\r_Tested" | awk -v RS="_" '{ print $0; }' | od -a 0000000 T esting cr nl T ested nl 0000020 nl 0000021
最有说服力的例子是在数据中有\r\n
,而不是记录分隔符:
$ echo -e "Testing\r\nTested_Hello_World" | awk -v RS="_" '{ print $0; }' | od -a 0000000 T esting nl T ested nl H 0000020 ello nl W orld nl nl 0000034
awk
在输入数据中盲目地将\r\n
转换为\n
,即使我们没有要求。
这个替换似乎是在应用记录分离之前发生的,这就解释了为什么RS="\r\n"
从来不匹配任何东西。 在awk
查找\r\n
,它已经在输入数据中用\n
代替了。