如何以优雅的方式对子文件夹中具有特定扩展名的所有文件执行操作?

如何以优雅的方式对子文件夹中具有特定扩展名的所有文件执行操作?

我目前最好的选择是:

for i in $(find . -name *.jpg); do echo $i; done

问题:不处理文件名中的空格。

注意:我还喜欢图形化的方式来执行此操作,例如“tree”命令。

答案1

规范的方法是做

find . -name '*.jpg' -exec echo {} \;

(替换\;为一次+传递多个文件)echo

或(GNU 特定的,尽管一些 BSD 现在也有它):

find . -name '*.jpg' -print0 | xargs -r0 echo

兹什:

for i (**/*.jpg(D)) echo $i

答案2

已经给出了更好的答案。

但请注意,空格并不是您给出的代码中的唯一问题。制表符、换行符和通配符也是一个问题。

IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done

那么只有换行符才是问题。

答案3

您提到的是人们在尝试读取文件名时面临的基本问题之一。有时,知识有限并对文件和文件夹结构有误解的人往往会忘记“在 UNIX 中一切皆文件" 。所以他们不明白他们还需要处理空格,因为文件名可以由 2 个或更多带有空格的单词组成。

解决方案 :因此,众所周知的方法之一是执行干净的阅读

我们在这里将读取所有存在的文件并将它们保存在一个变量中,下次进行所需的处理时,我们只需将该变量保留在引号内,这将保留带空格的文件名。这是执行此操作的基本方法之一,但是,这里其他人提供的其他答案也同样有效。

脚本 :

 find /path/to/files/ -iname "*jpg" | \
  while read I; do
   cp -v --parent "$I" /backup/dir/
  done

在这里,我通过给出文件的路径来读取文件,无论我正在读取什么,我都会将它们保存在变量 I 中,稍后我将在处理它时引用该变量以保留空格,以便正确处理它。

希望这能以某种方式帮助您。

答案4

在最新版本的 bash 中,您可以使用以下globstar选项:

shopt -s globstar
for file in **/*.jpg ; do
    echo "$file"
done

对于简单的操作,您甚至可以完全跳过循环:

echo **/*.jpg

相关内容