Answers:
您可以在某些外壳程序中使用高级globbing模式来匹配目录中的所有文件,但不包括与特定模式匹配的文件。例如,在ksh,bash或zsh中,命令
shopt -s extglob ## needed in bash only
setopt ksh_glob ## needed in zsh only
mv /source/!(*.bak) /destination
将移动所有文件/source
到/destination
除文件匹配*.bak
。在zsh中,您也可以编写/source/^*.bak
是否首次运行setopt extended_glob
,以及更一般的情况(再次要求setopt extended_glob
)/source/*~*.bak
(或/source/a*~*.bak
所有名称以开头a
的.bak
文件,文件除外,等等)。
Zsh具有批量复制/移动/链接命令,除其他与模式匹配的文件外,该命令可用于移动所有文件。例如,以下命令将所有文件*.bak
从/source
移到target
,然后.bak
在过程中将其添加到文件名:
autoload zmv
zmv '/source/(*)~*.bak' '/target/$1.bak'
有几个称为rename
浮动的命令。在Debian和Ubuntu上,/usr/bin/rename
是一个perl脚本,它将文件移动到由perl表达式生成的新名称。如果要排除文件,则可以通过不生成新名称来排除文件的重命名。例如,下面的命令(使用此特定rename
程序)移动的所有文件,除了*.bak
从/source
到/target
:
rename 's!/source!/target! unless m!\.bak$!' /source/*
您可以使用find
命令选择要移动的文件。例如,下面的命令将所有常规文件,除了*.bak
在/source
或子目录成/target
(注意,目录结构被破坏):
find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
或(如果要移动的文件很多,效率更高)
find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
rsync
是对包含/排除规则的概括,cp
并且scp
具有非常强大的包含/排除规则。例如,下面的命令除了复制所有文件*.bak
中/source
或子目录到/target
,尊重目录结构:
rsync -a --exclude '*.bak' /source/ /target/
pax
(除其他事项外)cp
是类固醇的另一种。它的排除规则不如rsync强大,但是它具有在复制文件时重命名文件的附加功能。如果将文件重命名为空字符串,则该文件将从副本中排除。例如,下面的命令复制所有文件除了*.bak
在/source
或子目录成/target
,和重命名文件.bak
中传递。
cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
上面的示例具有创建名为的目录的不幸副作用foo.bak
,可以通过find
与pax
以下方式结合使用来避免:
{ cd /source && find . -type f; } | \
pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
find
命令应该以\;
+
following {}
。
mv file1 file2 /path/to/destination
不会做您想做的事