![如何复制名称中包含数字20到32的文件](https://linux22.com/image/140998/%E5%A6%82%E4%BD%95%E5%A4%8D%E5%88%B6%E5%90%8D%E7%A7%B0%E4%B8%AD%E5%8C%85%E5%90%AB%E6%95%B0%E5%AD%9720%E5%88%B032%E7%9A%84%E6%96%87%E4%BB%B6.png)
我想将包含从 20 到 32 的数字的文件从 copyDest 复制到 PastDest。我错了什么?
cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest
谢谢。
答案1
|
是管道运营商。
cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest
是cp
通过管道传输到名称为从3[0-2]*
glob 扩展的第一个文件的命令的命令。要|
成为全局交替运算符,它必须具有(...)
in zsh
(但zsh
具有用于数字范围匹配的专用运算符)和@(...)
in ksh
(或bash
with extglob
on)。
所以,与zsh
:
cp -r ~/copyDest/(*[^0-9]|)<20-32>(|[^0-9]*) ~/pasteDest
如果没有(*[^0-9]|)
,它也会匹配 foo120
使用ksh
or (或在 内bash -O extglob
使用)或(在 内),等效项(除了文件复制的顺序之外)将如下所示:shopt -s extglob
bash
zsh -o kshglob
set -o kshglob
zsh
(
LC_ALL=C
cp -r ~/copyDest/?(*[^0-9])*(0)@(2[0-9]|3[0-2])?([^0-9]*) ~/pasteDest
)
对于 ksh 或 bash,在大多数系统和除 C 之外的大多数语言环境中,[0-9]
匹配比 0123456789 更多的字符,因此LC_ALL=C
(这也会影响 glob 扩展排序顺序)。如果您的文件名仅包含 ASCII 字符,则可以省略它,因为我认为任何正常系统上的任何语言环境都不会包含除 0123456789 之外的 ASCII 字符[0-9]
。其他替代方法是替换[0-9]
为[0123456789]
.
另请注意,除了 in 之外zsh -o kshglob
,如果模式与任何文件都不匹配,cp
则将使用文字参数(一个有效但不太可能的文件名)调用该参数.../?(*[^0-9])*(0)@(2[0-9]|3[0-2])?([^0-9]*)
,如果存在,则将复制该参数(cp
否则将返回错误)。在 中bash
,您可以使用该failglob
选项来获得更接近 的更理智的行为zsh
(如果模式不匹配则取消命令)。
上面我们特别注意复制名为foo20.txt
,的文件foo00020.txt
,但不复制名为foo120.txt
或 的文件foo200.txt
(即使它们的名称包含 20)。它仍然复制foo32.12.txt
或foo-1E-20.txt
或foo0x20.txt
文件。
如果你仍然想复制foo120
或foo200
文件,那么它就变得简单得多:
zsh
:cp -r ~/copyDest/*<20-32>* ~/pasteDest
bash -O extglob
和合作:cp -r ~/copyDest/*@(2[0123456789]|3[012])* ~/pasteDest
答案2
您没有阅读有关 shell 模式匹配的手册,并认为它与通常所说的“正则表达式”相同。您在示例中使用的运算符具有不同的含义这一事实*
应该暗示它们不同。
对于 bash(和其他一些 shell),您可以使用{,}
运算符来达到所需的效果:
cp -r ~/copyDest/*{2[0-9],3[0-2]}* ~/pasteDest
但要注意的是,存在差异。这和写作是一样的
cp -r ~/copyDest/*2[0-9]* ~/copyDest/*3[0-2]* ~/pasteDest
这意味着如果任何一个模式与任何文件都不匹配,它将作为参数传递给cp
,并cp
会抱怨该文件不存在。您可以设置nullglob
shell 选项来避免这种情况。
答案3
bash
方法。作为奖励,它会打印未找到匹配文件的号码。
[steve@instance-2 ~]$ find copyDest pasteDest
copyDest
copyDest/file15
copyDest/file20
copyDest/file25
copyDest/file32
copyDest/file33
pasteDest
[steve@instance-2 ~]$ cp -pr ~/copyDest/*{20..32}* pasteDest
cp: cannot stat ‘/home/steve/copyDest/*21*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*22*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*23*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*24*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*26*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*27*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*28*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*29*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*30*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*31*’: No such file or directory
[steve@instance-2 ~]$ find copyDest pasteDest
copyDest
copyDest/file15
copyDest/file20
copyDest/file25
copyDest/file32
copyDest/file33
pasteDest
pasteDest/file20
pasteDest/file25
pasteDest/file32
[steve@instance-2 ~]$
答案4
你需要进行模式匹配,而不是正则表达式匹配。查看 shell 的手册页。尝试类似的东西
ls *2[0-9]* *3[0-2]*
即通过提供两种模式来实现交替。