有没有办法mv
、cp
或任何文件操作,以便我可以指定我的所有文件不想受影响吗?
例如,假设我有一个包含文件file1
、file2
、 和 的文件夹file3
,我想移动file1
到file2
某个地方。我不想明确命名要移动的文件 ( mv file1 file2 /path/to/destination
),而是想命名这些文件不是移动并移动文件夹中的所有其他内容 ( mv --some-switch file3 /path/to/destination
)
答案1
您可以在某些 shell 中使用高级通配模式来匹配目录中除与特定模式匹配的文件之外的所有文件。例如,在 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
if 第一次运行setopt extended_glob
,并且更一般地(再次需要setopt extended_glob
)/source/*~*.bak
(或者对于名称以除files 等/source/a*~*.bak
开头的所有文件)。a
.bak
Zsh 有一个批量复制/移动/链接命令,可用于移动除与模式匹配的文件之外的所有文件。例如,以下命令将除
*.bak
from/source
之外的所有文件移动到target
,并.bak
在进程中添加其名称:autoload zmv zmv '/source/(*)~*.bak' '/target/$1.bak'
有几个命令称为
rename
浮动。在 Debian 和 Ubuntu 上,/usr/bin/rename
是一个 perl 脚本,用于将文件移动到由 perl 表达式生成的新名称。如果要排除文件,您可以通过不生成新名称来排除文件重命名。例如,以下命令(使用此特定程序)将除from 之外rename
的所有文件移动到:*.bak
/source
/target
rename 's!/source!/target! unless m!\.bak$!' /source/*
您可以使用该
find
命令选择要移动的文件。例如,以下命令将除*.bak
in/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
in/source
或子目录之外的所有文件复制到 中/target
,并遵守目录结构:rsync -a --exclude '*.bak' /source/ /target/
pax
是(除其他外)另一个cp
类固醇。它的排除规则并不像 rsync 那样强大,但它具有在复制文件时重命名文件的附加功能。如果将文件重命名为空字符串,则会将其从副本中排除。例如,以下命令将除*.bak
in/source
或子目录之外的所有文件复制到/target
,并将文件重命名为.bak
in 。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/