以下是我逐行读取文件的方法:
while read ROW
do
...
done < file
我不使用其他语法
cat file | while read ROW
do
...
done
因为管道创建了一个子shell并使我丢失了环境变量。 如果文件没有以换行结束,则会出现问题:未读取最后一行。在后一种语法中很容易通过回显换行符来解决这个问题:
(cat file; echo) | while read ROW
do
...
done
如果不打开子shell或创建临时文件(列表非常大),我如何在前一种语法中执行相同操作?
答案 0 :(得分:2)
#!/bin/bash
while read ROW
...
done < <(cat file ; echo)
答案 1 :(得分:2)
适用于所有shell的方法如下:
#!/bin/sh
willexit=0
while [ $willexit == 0 ] ; do
read ROW || willexit=1
...
done < file
一旦while read
遇到EOF,直接read
就会退出,因此不会处理最后一行。通过检查while之外的返回值,我们可以处理最后一行。在读取之后应该添加对$ ROW空虚的附加测试,因为否则最后一行以换行结束的文件将生成带空行的虚假执行,因此请将其设为
#!/bin/sh
willexit=0
while [ $willexit == 0 ] ; do
read ROW || willexit=1
if [ -n "$ROW"] ; then
...
fi
done < file
答案 2 :(得分:0)
POSIX的方法是通过命名管道。
#!/bin/sh
[ -p mypipe ] || mkfifo mypipe
(cat num7; echo) > mypipe &
while read line; do
echo "-->$line<--"
export CNT=$((cnt+1))
done < mypipe
rm mypipe
echo "CNT is '$cnt'"
$ cat infile
1
2
3
4
5$
$ (cat infile;echo) > mypipe & while read line; do echo "-->$line<--"; export CNT=$((cnt+1)); done < mypipe; echo "CNT is '$cnt'"
[1] 22260
-->1<--
-->2<--
-->3<--
-->4<--
-->5<--
CNT is '5'
[1]+ Done ( cat num7; echo ) > mypipe
答案 3 :(得分:0)
来自answer to a similar question:
while IFS= read -r LINE || [ -n "${LINE}" ]; do
...
done <file
IFS=
部分阻止read
删除前导和尾随空格(请参阅this answer)。
如果您需要采取不同的反应,具体取决于文件是否有尾随换行符(例如,警告用户),则必须对while
条件进行一些更改。