Bash sort-o在文件末尾追加换行符-为什么?

Bash sort-o在文件末尾追加换行符-为什么?,bash,sorting,Bash,Sorting,我正在处理一个小文本文件,其中有一个单词列表,我想在其中添加一个新词,然后进行排序。当我开始时,文件的末尾没有换行符,但在排序之后有。为什么?我可以避免这种行为吗?或者有没有办法把换行符去掉 例子: words.txt看起来像 apple cookie salmon 然后我运行printf“\norange”>>words.txt;sort words.txt-o words.txt 我使用printf而不是echo计算,这样可以避免换行,但是文件会读取 apple cookie orange

我正在处理一个小文本文件,其中有一个单词列表,我想在其中添加一个新词,然后进行排序。当我开始时,文件的末尾没有换行符,但在排序之后有。为什么?我可以避免这种行为吗?或者有没有办法把换行符去掉

例子:
words.txt
看起来像

apple
cookie
salmon
然后我运行
printf“\norange”>>words.txt;sort words.txt-o words.txt

我使用printf而不是echo计算,这样可以避免换行,但是文件会读取

apple
cookie
orange
salmon
#newline here
如果我只是运行
printf“\norange”>>words.txt
orange会出现在文件的底部,没有换行符,即

apple
cookie
salmon
orange

此行为在中明确定义:

输入文件应为文本文件,但排序实用程序应在以不完整的最后一行结尾的文件末尾添加换行符

作为UNIX“文本文件”,只有在所有行都以换行结束时才有效,如下所示:

文本文件-包含组织为零行或多行的字符的文件。这些行不包含NUL字符,任何行的长度都不能超过{LINE_MAX}字节,包括换行符。尽管POSIX.1-2008没有区分文本文件和二进制文件(参见ISO C标准),但许多实用程序在对文本文件进行操作时只会产生可预测或有意义的输出。具有此类限制的标准实用程序总是在其STDIN或INPUT files部分中指定“文本文件”


想想你要求排序做什么

你在问它“把所有的行都记下来,按顺序排列。”

您已经为它提供了一个包含四行的文件,它将其拆分为以下字符串:

"salmon\n"
"cookie\n"
"orange"
它尽职尽责地为您分类:

"cookie\n"
"orange"
"salmon\n"
然后将它们作为单个字符串输出:

"cookie
orangesalmon
"
这几乎肯定正是你不想要的

因此,如果您的文件缺少它应该具有的终止换行符,
sort
程序理解,很可能您仍然希望最后一行是一行,而不仅仅是一行的片段。它在字符串“orange”后添加一个\n,使其成为“orange\n”。然后可以正确排序,而不会将“橙色”与紧跟其后的任何行连接起来:

"cookie\n"
"orange\n"
"salmon\n"
因此,当它将它们作为单个字符串输出时,它看起来好多了:

"cookie
orange
salmon
"
您可以使用一系列方便的工具,如
awk
sed
perl
php
,甚至raw
bash
,从文件中去掉最后一个字符,即“salmon\n”结尾的字符。在其他地方,如:

但请不要这样做。您只会给所有其他必须处理您的文件的实用程序(如排序)带来问题。如果您假设在您的文件中没有终止换行符,那么您将使您的代码变得脆弱:工具链中“修复”错误的任何部分(就像这里的排序一样)都将“破坏”您的代码

相反,应该按照unix中处理文本文件的方式来处理它们:一系列“行”(零个或多个非换行字节的字符串),每个行后面都跟一个换行符

所以换行符是行终止符,而不是行分隔符


有一种编码方式,
print
s和
echo
s以换行符开头。这是错误的,原因有很多,包括创建格式错误的文本文件,以及导致程序输出与命令提示符连接
printf“orange\n”
是正确的样式,也更具可读性:维护代码的人一眼就能看出您正在打印单词“orange”和换行符,而
printf“\norange”
乍一看就像是在打印反斜杠和短语“no range”缺少空格。

排序
表明这是在帮你的忙。Mine总是报告
sort:warning:newline added
各种版本的
sort
具有不同的功能。仔细查看可用版本的手册页,可能会发现cmd arg
——无换行符或类似内容。今后,请将此类非编程相关Qs(IMHO)发布至或。祝你好运。没有尾随换行符的“文本文件”不是有效的UNIX文本文件。许多工具会完全忽略任何没有尾随换行符的行——例如,在读取时,任何
循环都会在这些行上退出,而不是处理它们。顺便说一句,单个尾随换行符不会创建空行(正如您在这里呈现的那样)——它只会确保行在完成之前,也就是说,不要让光标挂起等待更多内容,或者让程序读取器不清楚文件是否已完全刷新。感谢您的解释!这很有道理,现在你好像在“的任何部分”后面掉了一些文字。很好。为索赔提供实际参考是答案应该是怎样的,现在我为没有这样做感到难过。