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)
谢谢。
|
是管道运营商。
cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)
是通过cp
管道传输到名称为从3[0-2]*
glob展开的第一个文件的命令的命令。为|
是一个水珠交替操作,它有是内(...)
中zsh
(但zsh
具有用于数范围匹配的专用操作者)和@(...)
中ksh
(或bash
与extglob
上)。
所以,与zsh
:
cp -r ~/copyDest/(*[^0-9]|)<20-32>(|[^0-9]*) ~/pasteDest
Run Code Online (Sandbox Code Playgroud)
没有(*[^0-9]|)
,它也会匹配 foo120
使用ksh
或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
)
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.txt
或foo200.txt
(即使它们的名称包含 20)。它仍然复制foo32.12.txt
或foo-1E-20.txt
或foo0x20.txt
文件。
如果你仍然想复制foo120
或foo200
文件,那么它变得简单得多:
zsh
:
cp -r ~/copyDest/*<20-32>* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)bash -O extglob
和合作:
cp -r ~/copyDest/*@(2[0123456789]|3[012])* ~/pasteDest
Run Code Online (Sandbox Code Playgroud)您没有阅读有关 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
会抱怨该文件不存在。您可以设置nullglob
shell 选项来避免这种情况。
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)
当我需要处理编号文件时,我倾向于使用 for 循环和seq
:
for i in $(seq 20 32); do cp -r ~/copyDest/*${i}* ~/pasteDest; done
Run Code Online (Sandbox Code Playgroud)