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

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

我想将包含从 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(或bashwith extglobon)。

所以,与zsh

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

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

使用kshor (或在 内bash -O extglob使用)或(在 内),等效项(除了文件复制的顺序之外)将如下所示:shopt -s extglobbashzsh -o kshglobset -o kshglobzsh

(
  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.txtfoo-1E-20.txtfoo0x20.txt文件。

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

  • 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会抱怨该文件不存在。您可以设置nullglobshell 选项来避免这种情况。

答案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]*

即通过提供两种模式来实现交替。

相关内容