查找并复制Linux中包含模式的多个文件



当我需要复制多个文件到同一目录时,我可以:

  • cp文件{20 . .30}newLocation

但是当我将它与find结合使用时,它不起作用

  • 找到。- name '文件{20 . .30}' -exec cp '{}' newLocation ';'

我做错了什么?

{20..30}范围语法是Bash命令行解析器的一个特殊功能。它不是标准POSIX globing的一部分,例如find-name测试执行,并且在某些您可能希望它被Bash识别的上下文中,它甚至不能被Bash识别。

您已经知道我为您的示例案例推荐的更简单、更直接的替代方法。你也可以这样写

find . '(' -name 'file2[0-9]' -o -name file30 ')' -exec cp '{}' newLocation ';'

,但是如果范围的端点是动态确定的,那么这就不是很好地工作了。

如果使用find的目的是为了避免由于某些不存在的文件而引起的问题,那么您可以考虑这样处理它:

for f in file{20..30}; do
[[ -e "$f" ]] && cp "$f" newLocation
done

正如另一个帖子/答案所提到的,用()包围名称,中间加上-o-name

像这样的东西应该能够从你的输入文件/string中添加这些字符串。

#!/usr/bin/env bash
format() {
local f
declare -ag files
for f; do
files+=( -o -name "$f" )
done
}
format file{10..20}

现在检查"${files[@]}"

的值
declare -p files

输出
declare -a files=([0]="-o" [1]="-name" [2]="file10" [3]="-o" [4]="-name" [5]="file11" [6]="-o" [7]="-name" [8]="file12" [9]="-o" [10]="-name" [11]="file13" [12]="-o" [13]="-name" [14]="file14" [15]="-o" [16]="-name" [17]="file15" [18]="-o" [19]="-name" [20]="file16" [21]="-o" [22]="-name" [23]="file17" [24]="-o" [25]="-name" [26]="file18" [27]="-o" [28]="-name" [29]="file19" [30]="-o" [31]="-name" [32]="file20")

看看当它被用作find

的输入时会是什么样子
printf '%sn' "( ${files[*]} )"

输出
( -o -name file10 -o -name file11 -o -name file12 -o -name file13 -o -name file14 -o -name file15 -o -name file16 -o -name file17 -o -name file18 -o -name file19 -o -name file20 )

使用数组files作为find的输入

find . -type f ( "${files[@]:1}" ) -exec bash -c 'echo cp -v -- "$@" /destination' _ {} +
  • "${files[@]:1}"删除前面的-o

  • 如果您对输出满意,请删除echo,以便进行文件复制。


或者只使用globstarnullglob'

#!/usr/bin/env bash
shopt -s globstar nullglob
cp -v ./**/file{10..20} /destination

前面的./表示当前目录,可以是

/path/to/source/**/file{10..20}

其中/path/to/source/是所讨论的文件所在的目录。

最新更新