2012-02-04 158 views
6

我用下面的bash shell脚本列出的递归当前目录下的名为“.txt”文件的bash shell列表文件:使用“for”循环

#!/bin/bash 
for file in $(find . -type f -name "*.txt") 
do 
    echo $file 
    # Do something else. 
done 

然而,一些名为“.txt”文件在当前目录下有它们名字中的空格,例如“我的testing.txt”。列表被破坏,例如“我testing.txt”被列为

my 
testing.txt 

看来,“for”循环使用“空白”(空格,\ n等)来分隔的文件列表,但在我来说,我只想用“\ n”分隔文件列表。

有没有什么办法可以修改这个脚本来达到这个目的。任何想法。

在此先感谢。

+0

在bash中,我认为你使用'find ... -print0'和'IFS =“\ 0”',或者其他。这个话题肯定还有其他的问题。 – 2012-02-04 07:34:24

回答

7

如果你正在使用bash 4,只使用一个水珠:

#!/bin/bash                  

shopt -s globstar 

for file in **/*.txt 
do 
    if [[ ! -f "$file" ]] 
    then 
     continue 
    fi 
    echo "$file" 
    # Do something else.               
done 

请务必注明"$file",否则你会在其他地方有同样的问题。如果启用了globstar**将递归匹配文件和目录。

+0

谢谢。它适用于我的情况。 – user1129812 2012-02-04 08:24:47

7

是的,有find与NUL分隔的文件名,并使用read划上NUL。这将成功迭代任何文件名,因为NUL不是文件名的有效字符。

#!/bin/bash 
while IFS= read -r -d '' file; do 
    echo "$file" 
    # Do something else. 
done < <(find . -type f -name "*.txt" -print0) 

或者,如果# do something else是不是太复杂,你可以使用find-exec选项,而不必担心正确界定

+0

谢谢。但是这种方法对我来说似乎不太熟悉。我会稍后再尝试。 – user1129812 2012-02-04 08:17:06

+1

'find'的习惯使用就像这样。 'for $(find ...)'中的文件的问题恰恰是它将以空格分割。相反,使用'find ... |同时读文件'。为了正确处理带有换行符的文件名,需要使用“read”的附加选项,但是如果需要应对的只是空格,则可能会变得更加脆弱。 – tripleee 2012-02-04 10:52:25

+0

这种方法对我来说是一个很好的替代解决方案,因为它允许任意允许的文件名。该方法现在已经过测试,并且适用于我的案例。 – user1129812 2012-02-04 15:03:24