Bash循环读取文件每一行

11

我想在这里讨论两种逐行读取文件的方法:

#!/bin/bash    

while read line    
do    
    echo-e "$ line \ n"    
done <file.txt

#!/bin/bash    
exec 3<file.txt

while read line    
do    
    echo-e "$ line \ n"    
done

第一个版本能够正常工作,但我不理解它与文件一起使用的机制。而第二个版本的机制我理解了。但是在这里,我不理解为什么它会挂起并且没有打印任何东西。

4个回答

9
第一个循环有效是因为done后的重定向适用于整个循环,所以那里的read是从文件中读取而不是从脚本的标准输入中读取。
第二个版本挂起是因为read从文件描述符0(标准输入)读取,你没有在那里打字。exec行将文件描述符3重定向为从文件读取,但你没有从文件描述符3读取。
你可以通过使用以下方法来恢复第二个版本:
exec <file.txt

现在从指定文件中读取标准输入。

4
这可能对你有帮助:

这对您可能有用:

exec 3<file.txt

while read -u3 line
do
    echo -e "$line \n"
done

-u3 从文件描述符3中读取。

奇怪的是,echo 没有像ksh的 print 命令一样的补充开关。


3

你的脚本中有几个错误。

  1. $符号和变量名称之间应该没有空格。(可能是编辑错误)
  2. echo-e 之间应该没有空格。(可能是编辑错误)
  3. 在文件描述符处提及读取文件,而文件已经打开。你正在描述符0处读取文件,而exec是在描述符3处运行。

应该像这样:

#!/bin/bash    
exec 3<file.txt

while read line  
do
    echo -e "$line \n"
done <&3

1
read 行中的 <&3 能正常工作吗?在真正的 Bourne shell 的早期,重定向会在每次循环时执行,因此会产生一些有趣的效果(例如文件在每次迭代时关闭)。我可以相信它已经被修改了,以便事情变得更加合理。FWIW:当我在 MacOS X 上尝试使用 bash,并使用以下命令:while read line < somefile; do echo $line; done,我重复地获得了 somefile 的第一行...但是使用 <&3 符号,我确实获得了文件的后续行。要小心 - Jonathan Leffler
谢谢Jon,我用上面的脚本试了一下,在我的Mac上可以运行。http://cl.ly/ClDf 但这是一些有用的信息。我会记住的。我还是很新手bash。只是一直在学习awksed。但是我会开始阅读一些关于bash基础的书籍。 :) - jaypal singh
已经编辑了答案,在done语句后添加了<&3,而不是read语句。 - jaypal singh
这在Mac OS/X上运行良好,请不要忘记引号:while read line; do echo $line; done <"somefile" - Greg Burd

0

-u3 对我的目的非常好(仅读取下面一行)

#!/bin/bash

logs=(*Logs.txt)
[[ -e "${logs[0]}" ]] || exit 0

exec 3<"${logs[0]}"

while read -u3 line
do
        if [[ $(echo "$line"| grep -c SCSI_STATUS_CHECK_CONDITION) -eq 1 ]]; then
                read -u3 line
                echo "$line"
        fi
done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接