我有一个包含很多文件的文件夹。我想复制以这些名称开头的所有文件(用空格分隔):
abc abd aer ab-x ate
到另一个文件夹。我怎样才能做到这一点?
答案1
与csh
, tcsh
, ksh93
, bash
,fish
或 一起zsh -o cshnullglob
,您可以使用大括号扩展和通配为此(--
这些文件名不需要,但我认为它们只是示例):
cp -- {abc,abd,aer,ab-x,ate}* dest/
如果您不想使用大括号扩展,则可以使用 for 循环(此处为 POSIX/Bourne 样式语法):
for include in abc abd aer ab-x ate; do
cp -- "$include"* dest/
done
如果您有大量文件,则由于cp
每个包含调用一次,这可能会很慢。另一种方法是填充一个数组,然后从那里开始(此处ksh93
或zsh
最近的bash
语法):
files=()
includes=(abc abd aer ab-x ate)
for include in "${includes[@]}"; do
files+=( "$include"* )
done
cp -- "${files[@]}" dest/
答案2
关于大括号扩展与通配符的注释。
大括号扩展不是通配符(尽管其区别在它起源的 csh/tcsh 中并不像在其他 shell 中那样清晰)。它被执行前通配符。
所以,当你这样做时:
cp {a,b}* /dest
首先将其扩展为:
cp a* b* /dest
这意味着 shell 必须扩展两个 glob,即获取完整的文件列表两次,并查看哪些文件与模式匹配两次。
对于zsh
,这也意味着如果任何 glob 与任何文件都不匹配,则整个命令将被取消(您可以通过启用该cshnullglob
选项以像 csh 中一样运行来解决此问题)。
这也意味着如果你有
cp {a,ab}* /dest
cp
将复制ab*
文件两次。
这与以下内容不同:
cp @(a|b)* /dest
或ksh
或bash -O extglob
或zsh -o kshglob
或
cp (a|b)* /dest
的zsh
。那里,只有一glob,这样会更高效,文件只会被包含一次。
使用zsh
,如果您有数组中的前缀列表:
prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest
(上面,前缀被视为通配符)。即将数组的元素连接起来,|
并将结果视为 glob ( ~
)。
如果列表很大,您可能会发现执行cp
失败并显示“参数列表太长”错误。在这种情况下,您可以通过加载模块 ( ) 使用zsh
内置版本。cp
zsh/files
zmodload zsh/files
答案3
例如,我在当前目录中有这些文件:
1-s2.0-S0038092X0000058X-main.pdf ANNDHW.pdf HPcalculation2 1-s2.0-S0306261999000422-main.pdf ANNlee.pdf HPcalculation3 ANNCanada.pdf HPcalculation HPcalculation4
我想将从 HP 开始的所有文件移至文件夹:
./NewFolder/
我可以:
cp ./HP* ./NewFolder/
./HP*
会告诉linux我对从HP开始的所有文件感兴趣。相反,当我有兴趣移动所有以.pdf
.我可以*
把.pdf
:cp ./*.pdf ./NewFolder/
答案4
简单地你可以做
cp abc* abd* aer* ab-x* ate* DestinationPath
您的扩展问题的解决方案可以是
- 将所有文件名放入列表中,例如list0.txt
全部复制与
cp `cat list0.txt` DestinationPath # 文件名中不需要空格
或更好,
当读取-r文件时;执行 cp "$file" dest/ ;完成<list0.txt
笔记:
- “$file” 因为这样你就可以处理带有空格的名称
One Package.deb
-r
它可以保护您免受转义序列的影响。-r 反斜杠不充当转义字符。反斜杠被认为是该行的一部分。特别是,反斜杠-换行符对不能用作续行符