当我需要复制多个文件到同一目录时,我可以:
- 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
,以便进行文件复制。
或者只使用globstar
和nullglob
'
#!/usr/bin/env bash
shopt -s globstar nullglob
cp -v ./**/file{10..20} /destination
前面的./
表示当前目录,可以是
/path/to/source/**/file{10..20}
其中/path/to/source/
是所讨论的文件所在的目录。