我通常使用 read 命令逐行读取输入文件到 shell 脚本。如果未在输入文件 blah.txt 的最后一行末尾插入新行,则如下示例代码会产生错误结果。
#!/bin/sh
while read line
do
echo $line
done <blah.txt
所以如果输入文件读取类似 -
One
Two
Three
Four
我在四点后没有按回车键,脚本无法读取最后一行,并打印
One
Two
Three
现在如果我在四之后多留一个空行,比如,
One
Two
Three
Four
//blank line
输出打印所有行,包括四行。但是,当我使用 cat
命令读取一行时,情况并非如此;包括最后一行在内的所有行都被打印出来,而我不必在末尾添加一个额外的空行。
有人知道为什么会这样吗?我创建的脚本主要由其他人运行,因此他们没有必要在每个输入文件的末尾添加一个额外的空行。
多年来我一直在努力解决这个问题;如果您有任何解决方案,我将不胜感激(当然,cat
命令是其中之一,但我想知道 read 无法正常工作的原因)。
最佳答案
read
读取直到找到换行符或文件结尾,如果遇到文件结尾则返回非零退出代码。所以它很有可能既读取一行又返回非零退出代码。
因此,如果输入可能不会被换行符终止,则以下代码是不安全的:
while read LINE; do
# do something with LINE
done
因为 while
的主体不会在最后一行执行。
从技术上讲,不以换行符结尾的文件不是文本文件,文本工具可能会以奇怪的方式处理此类文件。但是,我总是不愿意依赖这种解释。
解决问题的一种方法是测试读取的内容是否为非空(-n
):
while read -r LINE || [[ -n $LINE ]]; do
# do something with LINE
done
其他解决方案包括使用 mapfile
将文件读入数组,通过一些实用程序管道文件,保证正确终止最后一行(grep .
,对于例如,如果您不想处理空行),或者使用 awk
(通常是我的偏好)之类的工具进行迭代处理。
请注意 -r
几乎肯定在 read
内置函数中是必需的;它导致 read
不重新解释输入中的 \
序列。
关于bash - 在 shell 脚本中使用 read 命令逐行读取输入文件会跳过最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17268113/