Windows下GNU awk v4.2.0处理DOS格式文件消除无效记录咨询
解决GNU awk处理Windows DOS格式文件时的无效记录问题
我明白你在Windows 7 x64 SP1下用GNU awk v4.2.0处理DOS换行文件时遇到的麻烦——CR/LF组合确实容易导致空记录或者字段解析异常,我给你几个靠谱的解决方案:
方法1:用BINMODE变量自动处理CRLF
GNU awk提供了BINMODE内置变量,专门解决Windows下的文本模式/二进制模式适配问题。设置BINMODE=3后,awk会自动将DOS格式的CRLF换行转换成UNIX风格的LF,这样默认的记录分隔符(\n)就能正常工作,不会留下多余的\r字符干扰记录解析:
# calculate the Greatest common divisor of each pair of inputs BEGIN { BINMODE=3 } # 启用二进制模式处理输入输出,自动转换CRLF { arg1 = $1; arg2 = $2; if ((arg1 == "") || (arg2 == "")) { next } while (arg1 != arg2) { if (arg1 > arg2) arg1 -= arg2 else arg2 -= arg1 } print "The greatest common divisor of", $1, "and", $2, "is", arg1 }
这个方法最省心,不需要手动处理换行符,适合所有Windows环境下的DOS格式文件。
方法2:精准设置记录分隔符RS
如果你不想依赖BINMODE,可以直接把RS设置成匹配CRLF或LF的正则表达式,确保每个完整的行被识别为一个记录,避免单独的\r产生空记录:
# calculate the Greatest common divisor of each pair of inputs BEGIN { RS="\r?\n" } # 匹配DOS的CRLF或UNIX的LF作为换行分隔符 { # 保险起见,移除记录末尾可能残留的回车符 sub(/\r$/,"",$0) arg1 = $1; arg2 = $2; if ((arg1 == "") || (arg2 == "")) { next } while (arg1 != arg2) { if (arg1 > arg2) arg1 -= arg2 else arg2 -= arg1 } print "The greatest common divisor of", $1, "and", $2, "is", arg1 }
这里RS="\r?\n"表示“可选的CR,加上必选的LF”,能兼容DOS和UNIX两种换行格式;sub(/\r$/,"",$0)则是确保记录末尾没有残留的\r,避免干扰字段的空值判断。
为什么你的原脚本会出问题?
你原来设置RS="[\r\n]",这个正则表示“单个的\r或者单个的\n”,所以DOS的CRLF会被当成两个独立的分隔符,中间就会产生一个空记录,这就是你看到的无效记录来源。
内容的提问来源于stack exchange,提问作者ScienceAmateur
相关产品推荐
相关产品推荐

