我如何使用for-each循环遍历在bash文件路径?(How do I use a for-eac

2019-07-20 12:04发布

下面的命令尝试枚举所有*.txt在当前目录中的文件并处理它们一个接一个:

for line in "find . -iname '*.txt'"; do 
     echo $line
     ls -l $line; 
done

为什么我会收到以下错误?:

ls: invalid option -- 'e'
Try `ls --help' for more information.

Answer 1:

下面是遍历文件提供更好的方式,因为它处理的空间和换行符的文件名:

find . -type f -iname "*.txt" -print0 | while IFS= read -r -d $'\0' line; do
    echo "$line"
    ls -l "$line"    
done


Answer 2:

更紧凑的版本在文件名称中的空格和换行的工作:

find . -iname '*.txt' -exec sh -c 'echo "{}" ; ls -l "{}"' \;


Answer 3:

for -loop将遍历所提供的串中的每个(空格分隔)条目。

其实你不执行find命令,但提供它是作为字符串(被通过迭代for -loop)。 取而代之的是双引号请使用反引号或$()

for line in $(find . -iname '*.txt'); do 
     echo "$line"
     ls -l "$line"
done

此外,如果你的文件路径/名称中包含空格此方法将失败(因为for -loop遍历空间分隔的条目)。 相反,它是更好地使用所描述的方法dogbanes答案 。


为了澄清你的错误:

至于说, for line in "find . -iname '*.txt'"; 遍历所有的空间分隔的条目,它们是:

  • -我的名字
  • '* .TXT'(我想...)

前两个不会导致错误(除了不希望的行为),但第三个是有问题的,因为它执行:

ls -l -iname

很多(bash)的命令可以将单个字符选项,因此-iname相同-i -n -a -m -e 。 瞧:你的invalid option -- 'e'的错误!



Answer 4:

使用命令替换 ,而不是引号来执行传递命令字符串,而不是找到:

for line in $(find . -iname '*.txt'); do 
     echo $line
     ls -l $line; 
done


文章来源: How do I use a for-each loop to iterate over file paths in bash?
标签: linux bash shell