如何在shell中从目录中提取某些文件?

如何在shell中从目录中提取某些文件?

我制作了一个简单的 shell 脚本,它采用命令行目录并将其所有内容提取到脚本运行的当前目录。

#!/bin/bash
cp -v -R $1/* . 

我想对此进行扩展,假设我想提取目录 A 中的所有 PNG 文件,仅有的PNG 文件。

我的第一个想法是搜索目录中以 .png 结尾的所有文件并对其进行分类,但我不知道如何仅将这些文件复制到目录中。

答案1

任何一个

find "$1" -name '*.png' -exec cp -v -- {} ./ \;

或者(使用 GNU cp)更有效

find "$1" -name '*.png' -exec cp -vt ./ -- {} +

或者如果你的 shell 支持它,你可以使用 globbing - 例如bash

shopt -s globstar

cp -v -- "$1"/**/*.png ./

答案2

当复制变得复杂时,rsync通常很有用:

rsync -mva --include '*/' --include '*.png' --exclude '*' "$1/" .

不过,在真正运行之前,请先进行一次试运行(选项-n:),以便您可以验证它是否符合您的要求:

rsync -nmva --include '*/' --include '*.png' --exclude '*' "$1/" .

怎么运行的

  • -v(可选)告诉 rsync 是详细的,这样你就可以看到发生了什么。

  • -a(可选)告诉 rsync 保留属性。

  • --include '*/'告诉 rsync 包含所有目录

  • --include '*.png'告诉 rsync 包含所有带.png后缀的文件。

  • --exclude '*'告诉 rsync 排除上面不匹配的所有文件。

  • -m告诉 rsync 不要复制接收端为空的目录。

请注意,必须按顺序指定包含/排除选项。

答案3

由于您显然使用的是 bash,因此您可以使用globstar文件名扩展功能:

shopt -s globstar
cp **/*.png /some/destination

谨防文件名冲突——只有一个文件名能够在副本中幸存下来!

相关内容