我有一个 CSV 文件,该文件是通过从 Excel 另存为 CSV 生成的。如果我执行“head”(或者实际上“grep”或其他任何内容),它只会打印第一行:
head -n 10 messy.csv
10,15,11,21
但如果我在文本编辑器或 Excel 中打开该文件,它会包含很多行:
10,15,11,21
9,11,17,19
7,11,24,18
...
head
在机器上的其他文件上工作得很好。
为什么是这样? (我怀疑这与行结尾有关,但我不知道是什么。)我该如何解决它?
答案1
我认为这与行结束有关。 Excel 将保存带有回车/换行结尾的文件,但head
只需要换行。
显示什么输出:
tr -d '\r' < messy.csv | head -10
如果它正确显示 10 行,那就是您的答案。
file
可以告诉您某些文本文件的行结尾(它将打印...,带有 CRLF 行终止符),但它不会对所有文本文件执行此操作(我相信如果它识别出该文件是其他文件,例如 HTML,它不会执行此操作)。
答案2
你有\r
仅有的作为第 2 行以后的行尾字符(至少到第 10 行)。第 1 行有\n
作为行结束符。例如。
printf 'ABC\nXYZ\r123\r' | head
输出(到屏幕)
ABC
这是一个展示与终端输出相关的工件。回\r
跳到行的开头,下一行将覆盖它,最后一行将被终端提示符完全或部分覆盖。
当最后一个\r
分隔行比提示符长时,则该行是部分地显示(超出提示符末尾) - 例如,在下面的示例输出中,终端提示符只是nn $
(5 个字符),其中nn
是发出的第 n 个命令)。
72 $ printf 'ABC\nXYZ\rabcdefghijklmnop\r'
ABC
73 $ fghijklmnop
要解决这个问题
sed -i.bak 's/\r$//; s/\r/\n/g' file
该-i.bak
选项导致输入file
被更新我nline 并进行备份file.bak
。如果您不想备份,只需使用-i
.
答案3
分析你的问题
head
行为不符合您的预期。换成一个简单的分析工具, od
看看到底是怎么回事:
od -cx messy.csv
然后看看如何head
处理这个文件:
head -2 messy.csv | od -cx
您会注意到,它head
正在处理\r
返回 ASCII 代码 ( 0x0d
),因为它是为以下目的而设计的:
制作原始类型 writer 的“回车符”。它只是带回当前光标位置,准备在“行首”写入下一个位置。
修理它
请参阅此处的正确sed
命令:
修复 Excel 文件中的“\r”
作为记录
这个 Microsoft 错误是一个胜利者:Excel 行尾的这种编码对于以下操作系统是错误的:Windows、Unix(所有)、MacOS X。
你无法超越它:)。
答案4
我认为正确的做法是:
head -10 file.txt
(打印起始 10 行)
另一种方式可以是:
cat file.txt | head -10