我正在处理一个小文本文件,其中包含一个单词列表,我想添加一个新单词,然后排序.我启动时文件末尾没有换行符,但排序后却没有换行符.为什么?我可以避免这种行为,还是有办法将换行删除?
words.txt 好像
apple
cookie
salmon
Run Code Online (Sandbox Code Playgroud)
然后我跑了 printf "\norange" >> words.txt; sort words.txt -o words.txt
我使用printf而不是echo来确定是否会避免换行,但文件会读取
apple
cookie
orange
salmon
#newline here
Run Code Online (Sandbox Code Playgroud)
如果我只是运行printf "\norange" >> words.txt橙色出现在文件的底部,没有换行符,即;
apple
cookie
salmon
orange
Run Code Online (Sandbox Code Playgroud)
此行为在POSIX规范中sort明确定义:
输入文件应为文本文件,但排序实用程序应在以不完整的最后一行结尾的文件末尾添加换行符.
因为UNIX"文本文件"仅在所有行以换行符结尾时才有效,如POSIX标准中所定义:
文本文件 - 包含组织为零行或多行的字符的文件.这些行不包含NUL字符,并且没有一行可以超过{LINE_MAX}个字节,包括换行符.尽管POSIX.1-2008不区分文本文件和二进制文件(请参阅ISO C标准),但许多实用程序在操作文本文件时仅产生可预测或有意义的输出.具有此类限制的标准实用程序始终在其STDIN或INPUT FILES部分中指定"文本文件".
想想你sort要做什么.
你问它"采取所有行,并按顺序排序."
你给它一个包含四行的文件,它分成以下字符串:
"salmon\n"
"cookie\n"
"orange"
Run Code Online (Sandbox Code Playgroud)
它尽职尽责地为您排序:
"cookie\n"
"orange"
"salmon\n"
Run Code Online (Sandbox Code Playgroud)
然后它将它们作为单个字符串输出:
"cookie
orangesalmon
"
Run Code Online (Sandbox Code Playgroud)
这几乎可以肯定是你不想要的.
因此,相反,如果你的文件丢失终止换行符,它应该有,该sort程序的理解是,最有可能的,你还是打算最后一行是一条线,而不仅仅是一个线的片段.它将\n附加到字符串"orange",使其成为"orange \n".然后它可以正确排序,没有"橙色"连接到它后面发生的任何行:
"cookie\n"
"orange\n"
"salmon\n"
Run Code Online (Sandbox Code Playgroud)
因此,当它将它们作为单个字符串输出时,它看起来好多了:
"cookie
orange
salmon
"
Run Code Online (Sandbox Code Playgroud)
您可以剥离的最后一个字符脱档,从"鲑鱼\n"结束的一个,使用各种方便的工具,如awk,sed,perl,php,甚至生bash.这在其他地方有所涉及,例如:
但请不要这样做.您只会给必须处理文件的所有其他实用程序带来问题,例如排序.如果你假设你的文件中没有终止换行符,那么你将使你的代码变得脆弱:工具链的任何"修复"你的错误的部分(如此处的排序)会"破坏"你的代码.
相反,将文本文件视为在unix中处理它们的方式:一系列"行"(零或更多非换行字节的字符串),每个字符后跟一个换行符.
因此换行符是行终止符,而不是行分隔符.
有一种编码风格,prints和echos用换行符引导.出于多种原因这是错误的,包括创建格式错误的文本文件,以及使程序的输出与命令提示符连接在一起.printf "orange\n"风格正确,而且更具可读性:一眼就能看出维护代码的人可以告诉你打印"橙色"字样和换行符,而printf "\norange"乍看之下就像打印一个反斜杠和短语"无范围"一样缺少空间.