【问题标题】:Bash while loop that reads file line by lineBash while循环逐行读取文件
【发布时间】:2012-01-24 04:24:28
【问题描述】:

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

#!/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

所以第一个版本可以正常工作,但我不了解文件的 while 循环工作机制。但我理解第二个版本的机制。但是在这里我不明白为什么它会挂起并且不打印任何东西。

【问题讨论】:

    标签: bash file-io while-loop


    【解决方案1】:

    第一个循环有效,因为done 之后的重定向适用于整个循环,因此read 从文件中读取,而不是从脚本的标准输入中读取。

    第二个版本挂起,因为read 从文件描述符 0 读取,这是标准输入,并且您没有在此处键入任何内容。 exec 行重定向文件描述符 3 以从文件中读取,但您不是从文件描述符 3 中读取。

    您可以使用以下方法拯救第二个:

    exec <file.txt
    

    现在从命名文件中读取标准输入。

    【讨论】:

      【解决方案2】:

      这可能对你有用:

      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
        

        【讨论】:

        • &lt;&amp;3read 线上是否有效?在真正的 Bourne shell 的糟糕旧时代曾经是这种情况,每次循环都会进行重定向,所以你会得到有趣的效果(比如每次迭代都关闭文件)。我完全可以相信从那时起它已经被修改了,所以事情变得更加理智了。 FWIW:当我在 MacOS X 上尝试 bash 时,while read line &lt; somefile; do echo $line; done,我得到了 somefile 的第一行反复回显...但是使用 &lt;&amp;3 符号,我确实得到了文件的连续行。 小心
        • 感谢乔恩,我尝试使用上述脚本,它在我的 Mac 上运行。 cl.ly/ClDf 但这是一些有用的信息。会记住的。我对 bash 还是很陌生。刚刚在学习awksed。但是会开始一些关于 bash 基础的书籍。 :)
        • 已将答案编辑为在done 语句之后使用&lt;&amp;3 而不是read 语句。
        • 这在 Mac OS/X 上运行良好,不要忘记引号:while read line;回声 $line;完成
        【解决方案4】:

        -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
        

        【讨论】:

          猜你喜欢
          • 2013-03-28
          • 2018-09-05
          • 1970-01-01
          • 2013-10-04
          • 2015-04-26
          • 2013-10-12
          • 2013-04-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多