这是file.txt
:
foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
the quick brown fox jumps over the lazy dog
这是我在终端尝试的内容:
user@notebook:~/Desktop$ cat file.txt
foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
the quick brown fox jumps over the lazy dogmuser@notebook:~/Desktop$ cat read.sh
while read -r line
do
echo $line
done < file.txt
user@notebook:~/Desktop$ ./read.sh
foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
我的问题是:为什么read.sh
不显示cat file.txt
之类的最后一行?
答案 0 :(得分:7)
因为file.txt中没有行尾,如果你:
$ od -c file.txt
0000000 f o o : b a r : b a z : q u x :
0000020 q u u x \n o n e : t w o : t r e
0000040 e : f o u r : f i v e : s i x :
0000060 s e v e n \n a l p h a : b e t a
0000100 : g a m m a : d e l t a : e p s
0000120 i l o n : z e t a : e t a : t e
0000140 t a : i o t a : k a p p a : l a
0000160 m b d a : m u \n t h e q u i c
0000200 k b r o w n f o x j u m p
0000220 s o v e r t h e l a z y
0000240 d o g
文件末尾没有\n
。
echo
将在您收到消息时添加新行(如果没有消息)。
答案 1 :(得分:4)
其他答案是正确的,file.txt
的末尾根本没有换行符。
大多数文本编辑器会自动结束带换行符的文件,即使nano
也这样做。但是你的文件是由脚本生成的,对吗?
要重现此行为,您所要做的就是:
echo -n 'hello world' >> file.txt
-n
标志告诉echo不输出尾随换行符。
此外,如果您希望read
代码有效,可以使用此代码:
while read -r line
do
printf "%s\n" "$line"
done < file.txt
[[ -n $line ]] && printf '%s' "$line"
这样做是因为实际上read
会将最后一行放入变量中,但它也会返回 false ,从而打破了while循环。
答案 2 :(得分:1)
您的输入文件不会以换行符结尾。
cat file
只是将文件内容复制到标准输出。它由字符而不是行操作,因此它不关心文件是否以换行符结尾。但如果它不以换行符结尾,则不会在输出中添加一个。
read -r line
会在变量中读取一行。如果该行以换行符结尾,它将仅报告成功。如果输入的最后一行未以换行结束,则会报告错误,就好像已达到EOF一样。因此,循环在尝试读取最后一行时终止,而不是返回该行。这就是为什么脚本永远不会显示以the quick brown fox
开头的行。
通常,Unix文本文件程序仅定义为以换行符结尾的文本文件。如果它没有换行,它们对最后一行的处理通常不会被指定。
答案 3 :(得分:0)
您的file.txt
在最后一行末尾不包含换行符。因此cat
没有显示它。
请注意,read.sh
根本不显示最后一行...在read.sh
中,read
正在等待完整的输入行,并且因为最后一行未终止通过换行符,所以实际上并没有阅读。