awk的print语句中重复条目无法正常输出的原因是什么?
问题根本原因
你遇到的现象和awk的去重逻辑完全无关,核心是输入文件采用了Windows格式的CRLF换行符(\r\n),而非Unix格式的LF换行符(\n)。
Windows格式的文件每行末尾会携带一个不可见的回车符\r,这个字符会被awk识别为行内容的一部分,直接包含在$0以及行内最后一个字段的末尾。终端渲染内容时,一旦遇到\r就会把光标移动到当前行的行首,后续输出的内容会直接覆盖当前行已有的内容,才会出现“只打印了一次内容”的错觉。
举个实际例子,假设你的输入行原始内容为field1 field2\r\n,awk读取后会识别为:
$0=field1 field2\r$1=field1$2=field2\r
当你执行awk '{print $0 $0}'时,实际输出的完整内容为field1 field2\rfield1 field2\r\n,终端渲染时第一个\r会把光标拉回行首,第二遍的field1 field2直接覆盖掉第一遍的内容,最终你只能看到一行field1 field2的输出。你可以通过awk '{print $0 $0}' 你的输入文件 | cat -A命令查看原始输出,就能看到隐藏的\r字符,确认awk实际打印了两次内容。
解决方法
方法1:提前转换文件格式
使用dos2unix工具把输入文件转为Unix格式后再执行awk语句即可:
dos2unix 你的输入文件名 awk '{print $0 $2}' 你的输入文件名
方法2:awk语句内直接处理
不需要修改原文件,直接在awk中先移除行尾的\r再做后续处理:
awk '{sub(/\r$/, ""); print $0 $2}' 你的输入文件名
内容的提问来源于stack exchange,提问作者Dominique
相关产品推荐
相关产品推荐

