如何在awk脚本中去除字段CR/LF,解决最后列无法显示问题
解决awk中DOS换行符导致最后一列带CR的问题
完全懂你的困扰!DOS格式的换行符是\r\n,而awk默认用\n作为行分隔符,所以读入时会把行尾的\r(回车符)留在最后一个字段里,导致你处理最后一列时出现异常(比如输出看不见、数组键值异常等)。不用dos2unix的话,在awk里有几种简单直接的解决方式:
方法1:全局清除行尾的CR
在每行处理前,用gsub去掉行尾的回车符,这样所有字段都会恢复正常:
{ # 只匹配行尾的CR并删除,不会影响行内可能存在的(极少出现)CR gsub(/\r$/, "") # 下面放你原来的脚本逻辑 if (!keys[$3]++) { b[++c] = $3; row1 = row1 OFS $3; } # 现在处理最后一列($NF)就不会带CR了 # 比如 print $NF 会正常显示内容 }
如果你的awk版本不支持\r,可以用八进制转义符\015代替:gsub(/\015$/, "")
方法2:直接设置记录分隔符为DOS换行符
如果你的文件全是DOS格式,直接在BEGIN块里把记录分隔符(RS)设为\r\n,这样awk读入每行时会自动去掉末尾的CR,最彻底:
BEGIN { RS = "\r\n" # 告诉awk用DOS的换行符作为行分隔符 OFS = " " # 保持你需要的输出字段分隔符 } { # 你的原有逻辑完全不用改,所有字段都已经是干净的了 if (!keys[$3]++) { b[++c] = $3; row1 = row1 OFS $3; } }
方法3:只清除最后一个字段的CR
如果你确定只有最后一个字段带CR,也可以精准处理$NF(最后一个字段变量):
{ # 给最后一个字段去掉末尾的CR sub(/\r$/, "", $NF) # 继续你的原有逻辑 if (!keys[$3]++) { b[++c] = $3; row1 = row1 OFS $3; } }
这三种方法都能完美解决你的问题,根据你的文件情况选就行——如果全是DOS格式,方法2最省心;如果混合了不同换行格式,方法1或3更稳妥。
内容的提问来源于stack exchange,提问作者gungu
相关产品推荐
相关产品推荐

