2011-12-20 52 views
10

有逐行读取一个文件行两种方式,我想在这里讨论:猛砸while循环,通过线读取文件中的行

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

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

回答

9

第一个循环的作用是因为done之后的重定向适用于整个循环,所以read有文件读取,而不是来自脚本的标准输入。

第二个版本挂起,因为read从标准输入的文件描述符0中读取,并且您没有在其中键入任何内容。该exec行重定向文件描述符3从文件中读取,但你无法从文件描述符读取3.

您可以通过使用救出第二:

exec <file.txt 

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

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

不'<&3'在'read'线工作?它曾经是这样的,回到真正的Bourne shell的旧时代,重定向将在每一次循环中完成,因此你得到了有趣的效果(比如每次迭代关闭文件)。我可以相信,自那时起它已经被修改,所以事情的工作更加理智。 * FWIW *:当我在MacOS X上尝试'bash'时,使用:'while read line 2011-12-20 06:41:04

+0

感谢乔恩,我试着用上面的脚本,它在我的Mac上工作。 http://cl.ly/ClDf但这是一些有用的信息。我不记得它。对于bash我还是很新的。刚刚学习'awk'和'sed'。但会启动一些有关bash基础知识的书籍。 :) – 2011-12-20 06:50:30

+0

已编辑答案在'done'语句而不是'read'语句之后具有'<&3'。 – 2011-12-20 17:46:40

4

这可能会为你工作:

exec 3<file.txt 

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

-u3从文件描述符3读取

奇怪的是,echo没有补码开关lik e ksh的print命令。

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