如何复制名称中包含数字从 20 到 32 的文件

use*_*427 5 shell bash wildcards command

我想将包含从 20 到 32 的数字的文件从 copyDest 复制到 pastDest。我做错了什么?

cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)

谢谢。

Sté*_*las 9

| 是管道运营商。

cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)

是通过cp管道传输到名称为从3[0-2]*glob展开的第一个文件的命令的命令。为|是一个水珠交替操作,它有是内(...)zsh(但zsh具有用于数范围匹配的专用操作者)和@(...)ksh(或bashextglob上)。

所以,与zsh

cp -r ~/copyDest/(*[^0-9]|)<20-32>(|[^0-9]*) ~/pasteDest
Run Code Online (Sandbox Code Playgroud)

没有(*[^0-9]|),它也会匹配 foo120

使用kshbash -O extglob(或使用shopt -s extglobbash)或zsh -o kshglobset -o kshglobzsh),等价物(除了文件复制的顺序)看起来像:

(
  LC_ALL=C
  cp -r ~/copyDest/?(*[^0-9])*(0)@(2[0-9]|3[0-2])?([^0-9]*) ~/pasteDest
)
Run Code Online (Sandbox Code Playgroud)

使用 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.txtfoo200.txt(即使它们的名称包含 20)。它仍然复制foo32.12.txtfoo-1E-20.txtfoo0x20.txt文件。

如果你仍然想复制foo120foo200文件,那么它变得简单得多:


Ral*_*edl 6

您没有阅读有关 shell 模式匹配的手册,并认为它与通常称为“正则表达式”的内容相同。*您在示例中使用的运算符具有不同含义这一事实应该暗示它们不相同。

使用 bash(和其他一些 shell),您可以使用{,}运算符来获得所需的效果:

cp -r ~/copyDest/*{2[0-9],3[0-2]}* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)

但要注意存在差异。这和写作一样

cp -r ~/copyDest/*2[0-9]* ~/copyDest/*3[0-2]* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)

这意味着如果任一模式与任何文件都不匹配,它将作为参数传递给cp,并cp会抱怨该文件不存在。您可以设置nullglobshell 选项来避免这种情况。

  • 没有必要居高临下……乍一看,他们看起来很相似。不过,其余的答案很有用,谢谢。 (9认同)
  • OP 的尝试,如果它有效,也将匹配 ```foo200.txt``` 或 ```foo120.txt```,所以大概这些匹配被 OP 情况的更大的未说明的上下文所禁止;也许日志文件仅从 1 - 64 编号。 (4认同)

ste*_*eve 6

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 ~]$
Run Code Online (Sandbox Code Playgroud)

  • 这种方法(或 zsh 的 `&lt;20-32&gt;`)是最干净的,因为它不需要人类从数字序列中逆向工程模式。 (3认同)

Zol*_*tan 5

当我需要处理编号文件时,我倾向于使用 for 循环和seq

for i in $(seq 20 32); do cp -r ~/copyDest/*${i}* ~/pasteDest; done
Run Code Online (Sandbox Code Playgroud)