背景
在 Linux 中,您可以:
- 列出一组文件
ls Filename*
- 删除一组文件
rm Filename*
- 移动一组文件
mv Filename* /New/Directory
- 但是您不能使用以下命令复制一组文件:
cp Filename* *.bak
更改 Linuxcp
命令以复制文件组
我有一组文件要复制,而无需逐个输入名称并使用以下cp
命令:
$ ls gmail-meta3*
gmail-meta3 gmail-meta3-REC-1558392194-26467821
gmail-meta3-LAB-1558392194-26467821 gmail-meta3-YAD-1558392194-26467821
如何使用旧的 DOS 命令之类的东西copy gmail-meta3* *.bak
?
我不想四次输入类似的命令:
cp gmail-meta3-LAB-1558392194-26467821 gmail-meta3-LAB-1558392194-26467821.bak
我正在寻找一个脚本/函数/应用程序,它接受新旧文件名组的参数,而不是带有硬编码文件名的东西。例如,用户可以键入:
copy gmail-meta3* *.bak
或者他们可能会输入:
copy gmail-meta3* save-*
sed
以下是适用于此任务的一种非典型用法示例:这样,实际上
sed
不会更改文件,因为我们没有提供任何命令''
,但是由于该选项-i[suffix]
,它会为每个文件创建一个备份副本。我在搜索时发现了这种方法 是否有任何方法可以创建文件的备份副本,而无需输入两次文件名?您可以使用
find
:这将在当前目录中找到
.
名称与 glob 模式匹配的所有文件(注意模式周围的单引号以防止 shell 通配符)。对于找到的每个文件,它将cp
从 name 执行到 name.bak。这 \; 最后确保它将单独执行每个文件,而不是一次传递所有文件。最大深度为 1 只搜索当前目录而不是向下递归。您可以将
for
循环与bash
. 通常,我只会将其键入为单行,因为这不是我经常执行的任务:但是,如果您需要它作为脚本:
用法类似于
rename
。去测试:最接近 DOS 范式的可能是
mcp
(来自mmv
软件包):如果
zsh
可用,它的贡献zmv
模块可能更接近一点:ls
无论如何,我都会避免-您自己的答案的变体对空格(包括换行符)是安全的也许
rsync 唯一解决方案
如果您只想备份文件,可以将它们复制到新目录
rsync /path/to/dir/Filename* /path/to/backupdirectory
这会将
Filename
文件从复制/path/to/dir/
到/path/to/backupdirectory
。rsync + 文件重命名
如果你想让你的备份文件有一个后缀,那么事情就会变得很糟糕
rsync
......rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak
这将用现有文件 ( ) 覆盖现有文件……
-I
但前提是它们 (-u
) 较新(它们不是)并创建带有后缀的备份。您也可以在同一目录中执行此操作。但最好排除现有备份。
rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak --exclude '*.bak'
我把这个单行代码写进了我的
~/.bashrc
.find
我想可以发布更好的答案。甚至更好的答案可以用 C 语言编写。希望这个问答能得到更好的答案:for f in "$1"*; do
:$1
是gmail-meta3
参数,f
是匹配的文件列表。结合 gmail-meta3、gmail-meta3-LAB-9999 等的这种方式,执行以下操作[[ ! "$f" == *"$2" ]] &&
:$f
和f
上面一样。$2
是.bak
传递的参数。结合这意味着如果文件名没有以.bak
(因为我们不想复制.bak
和创建.bak.bak
)结尾,那么请执行以下操作cp -a "$f" "$f$2";
将 gmail-meta3 复制到 gmail-meta3.bak 等。done
: 循环并获取gmail-meta3
* 列表中的下一个文件名。cps gmail-meta3 .bak
样本输出以这个问题为例,它的实际表现如下:
注意:这将
-a
标志与cp
命令一起使用以保留时间戳并让您更好地掌握文件备份。请注意文件副本的日期和时间与原件完全相同。如果
-a
省略该参数,它们将被赋予当前日期和时间,并且看起来不像真正的备份,只是文件大小相同。这个应该按要求做:
用法:
我选择了
?
因为#
必须在它是模式的第一个字符时被引用,否则它被识别为注释的开始。测试:
添加后缀的一些早期版本的脚本:
类似于@WinEunuuchs2Unix 答案,但我认为更灵活且不解析
ls
:把它放在你的
.bashrc
.用法:
或者,后缀作为最后一个参数(via和via):
用法:
实现您的要求的另一种方法是将文件复制到临时目录并使用
rename
命令重命名它们。如果你需要它作为脚本,你可以像这样使用它
你可以像这样使用它:
这是一个例子