Linux 如何对指定路径下的所有文件执行 for-each 循环?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15065010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:07:02  来源:igfitidea点击:

How to perform a for-each loop over all the files under a specified path?

linuxbashshell

提问by 0x90

The following command attempts to enumerate all *.txtfiles in the current directory and process them one by one:

以下命令尝试枚举*.txt当前目录中的所有文件并一一处理:

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

Why do I get the following error?:

为什么会出现以下错误?:

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

采纳答案by dogbane

Here is a better way to loop over files as it handles spaces and newlines in file names:

这是循环文件的更好方法,因为它处理文件名中的空格和换行符:

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

回答by Jens Erat

Use command substitutioninstead of quotes to execute find instead of passing the command as a string:

使用命令替换而不是引号来执行 find 而不是将命令作为字符串传递:

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

回答by Veger

The for-loop will iterate over each (space separated) entry on the provided string.

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

You do not actually execute the findcommand, but provide it is as string (which gets iterated by the for-loop). Instead of the double quotes use either backticks or $():

您实际上并未执行该find命令,而是将其作为字符串提供(由for-loop进行迭代)。而不是双引号使用反引号或$()

ls -l -iname

Furthermore, if your file paths/names contains spaces this method fails (since the for-loop iterates over space separated entries). Instead it is better to use the method described in dogbanes answer.

此外,如果您的文件路径/名称包含空格,则此方法将失败(因为for-loop 遍历空格分隔的条目)。相反,最好使用dogbanes answer 中描述的方法。



To clarify your error:

澄清你的错误:

As said, for line in "find . -iname '*.txt'";iterates over all space separated entries, which are:

如前所述,for line in "find . -iname '*.txt'";迭代所有空格分隔的条目,它们是:

  • find
  • .
  • -iname
  • '*.txt' (I think...)
  • .
  • -我的名字
  • '*.txt'(我认为...)

The first two do not result in an error (besides the undesired behavior), but the third is problematic as it executes:

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

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

A lot of (bash) commands can combine single character options, so -inameis the same as -i -n -a -m -e. And voila: your invalid option -- 'e'error!

许多 (bash) 命令可以组合单字符选项,因此-iname-i -n -a -m -e. 瞧:你的invalid option -- 'e'错误!

回答by jserras

More compact version working with spaces and newlines in the file name:

使用文件名中的空格和换行符的更紧凑的版本:

##代码##