如何使用for-each循环遍历bash中的文件path?
以下命令尝试枚举当前目录中的所有*.txt
文件并逐个处理它们:
for line in "find . -iname '*.txt'"; do echo $line ls -l $line; done
为什么我得到以下错误?
ls: invalid option -- 'e' Try `ls --help' for more information.
当处理文件名中的空格和换行符时,这是更好的方式来循环文件:
find . -type f -iname "*.txt" -print0 | while IFS= read -r -d $'\0' line; do echo "$line" ls -l "$line" done
for
-loop将迭代所提供的string上的每个(空格分隔)条目。
你实际上并不执行find
命令,而是提供它作为string(它被for
-loop迭代)。 而不是双引号使用反引号或$()
:
for line in $(find . -iname '*.txt'); do echo "$line" ls -l "$line" done
此外,如果文件path/名称包含空格,则此方法失败(因为for
循环遍历空格分隔的条目)。 相反,最好使用描述在狗狗的答案 。
澄清你的错误:
如上所述, for line in "find . -iname '*.txt'";
迭代所有空格分隔的条目,它们是:
- 找
- 。
- -我的名字
- '* .txt'(我认为…)
前两个不会导致错误(除了不需要的行为之外),但是第三个在执行时是有问题的:
ls -l -iname
很多(bash)命令可以结合单个字符选项,因此-iname
与-i -n -a -m -e
。 瞧:你的invalid option -- 'e'
错误!
在文件名中使用空格和换行符更紧凑的版本:
find . -iname '*.txt' -exec sh -c 'echo "{}" ; ls -l "{}"' \;
使用命令replace而不是引号来执行查找,而不是将该命令作为string传递:
for line in $(find . -iname '*.txt'); do echo $line ls -l $line; done