首页 > 解决方案 > 带有 CRLF 行结尾的 Linux 和 mingw64 上的不同 awk 结果

问题描述

在 Linux 上:

echo -n $'boo\r\nboo\r\n' | awk $'BEGIN { RS="\\n" } {gsub("boo","foo"); print}' | cat -v

返回预期的

foo^M
foo^M

但是,在 mingw64(Windows 的 git bash)上,相同的命令返回:

foo
foo

没有回车。

我尝试明确设置记录分隔符,因为两个平台之间的默认值可能不同,但是 mingw64 上的 awk 仍在咀嚼回车。我怎样才能让 awk 在 mingw64 上的 Linux 上做同样的事情?请注意,awk 版本略有不同(Linux 上的 GNU Awk 4.0.2 和 mingw64 上的 GNU Awk 4.2.1),但除非存在某种错误,否则我不认为这很重要。

请注意,由于在 mingw64 上,awk 中特别发生了一些事情:

echo -n $'boo\r\nboo\r\n' | cat -v

返回预期:

boo^M
boo^M

标签: awkmingwmingw-w64

解决方案


搜索了一段时间后,我发现了这个问题,并且从这个答案中:

这是由 C 库完成的,要阻止它发生,您应该将 awk BINMODE 变量设置为 3

我将您的代码更改为:

echo -n $'boo\r\nboo\r\n' | awk -v BINMODE=3 $'BEGIN { RS="\\n" } {gsub("boo","foo"); print}' | cat -v

并在 Unix、Linux、MacOS 和 Windows 上进行了尝试,都产生了这个输出:

foo^M
foo^M

-v BINMODE=3您正在寻找的也是如此。
请注意,只有-v BINMODE=3此开关和在代码方式工作之前。
通常我们可以通过-vswitch、in BEGINblock 或在文件之前的 code 之后将变量传递给 awk,
但在这种情况下,我尝试了这三种方式,只管用-v BINMODE=3
猜猜这与awk's 的编译过程有关。

示例(在cygwinWindows 下):

$ echo -n $'boo\r\nboo\r\n' | awk -v BINMODE=3 '1' | cat -v    
boo^M                                                          
boo^M                                                          

$ echo -n $'boo\r\nboo\r\n' | awk 'BEGIN{BINMODE=3}1' | cat -v 
boo                                                            
boo                                                            

$ echo -n $'boo\r\nboo\r\n' | awk '1' BINMODE=3 | cat -v       
boo                                                            
boo                  

在其他提到的平台下,它们都产生:

boo^M
boo^M

推荐阅读