Bash逐行读文件
用 Bash 处理文件时,经常有一个需求是逐行读取文件的内容,并完成一定操作,那么应该如何读取文件呢?
通过搜索,我们不难得出如下的答案,但是这个是错误的!
while read line; do
echo $line
done < filename.txt
怎么错了?
当我们的文件最后一行没有换行符时,最后一行并不会被打印出来。
例如,我的 filename.txt
长这样(第4行最后的 %
是提示我们文件没有以换行符结束的标志,不是文件内容):
$ cat filename.txt
1
2
3%
此时,运行上述 Bash 代码会得到:
$ while read line; do
echo $line
done < filename.txt
1
2
为什么错了?
我们可以看到,上面的 read
的颜色和 echo
一样,说明这是个内置的函数,通过查询Bash文档的Builtin章节得知
The exit status is zero, unless end-of-file is encountered, …
退出的状态码是0,除非读到了 EOF 等内容
这里我们知道了,在读到第三行的时候,read
确实会把读到的内容赋值给 line
,但是因为其退出状态不是 0
,因此 while
循环的条件不被满足,因此无法执行循环中的内容(echo $line
)。
如何改正?
既然是因为 while
循环使用了 read
的退出码,那只要改个条件即可(这个条件既可以实现最后一行为true
,同时又避免了死循环):
while read line || [ -n "$line" ] ; do
echo $line
done < filename.txt