如何通过通配符复制多个文件?

如何通过通配符复制多个文件?

我有一个文件夹,里面有许多文件 ABC.* (大约有 100 个这样的文件)。我想将它们全部复制到名称以 DEF 开头的新文件中。*

所以,我想要

ABC.Page1
ABC.Page2
ABC.Topic12
...etc

复制到

DEF.Page1
DEF.Page2
DEF.Topic12
...etc

使用批处理命令(在 BASH 或类似命令中)执行此操作的最简单方法是什么?我正在考虑涉及 sed 或 awk 或 xargs 的问题,但我很难弄清楚语法。我可以编写一个 Python 脚本,但我认为可能有一个不太复杂的命令行解决方案。

答案1

在 bash 中这样的事情怎么样:

for file in ABC.*; do cp "$file" "${file/ABC/DEF}";done

您可以通过将 echo 放在 cp 命令前面来测试它:

for file in ABC.*; do echo cp "$file" "${file/ABC/DEF}";done

答案2

为了有效地处理大量文件,最好避免cp为每个文件启动不同的进程。一种方法是复制然后使用重命名它们prenamerename在基于 Debian 的发行版上默认符号链接到此)。使用这个和Linux mktemp

tmp=$(mktemp -d --tmpdir=.)
cp ABC.* "$tmp"
prename "s:$tmp/ABC:DEF:" "$tmp/"*
rmdir "$tmp"

更新

实际上pax可能是更好的方法:

pax -rws '/^ABC/DEF/' ABC.* .

不幸的是,尽管它pax同时是 POSIX 和 Linux 标准库,但目前很少有发行版默认包含它。

答案3

tar会非常快地为您做这件事。

测试

首先我创建了 2 个目录和 10 个文件:

% mkdir test1 test2 ; cd test1
% for n in `seq 1 10` ; do touch ABC.file$n ; done
% ls

> ABC.file1   ABC.file2  ABC.file4  ABC.file6  ABC.file8
> ABC.file10  ABC.file3  ABC.file5  ABC.file7  ABC.file9

然后我复制了它们:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC/DEF/' -xf -
% ls ../test2

> DEF.file1   DEF.file2  DEF.file4  DEF.file6  DEF.file8
> DEF.file10  DEF.file3  DEF.file5  DEF.file7  DEF.file9

转换

因此 GNUtar将接受sed --transform=EXPRESSION文件重命名。这甚至可以仅重命名某些文件。例如:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC\(.*[0-5]\)/DEF\1/' -xf -
% ls ../test2

> ABC.file6  ABC.file8  DEF.file1   DEF.file2  DEF.file4
> ABC.file7  ABC.file9  DEF.file10  DEF.file3  DEF.file5

这是一个优势。

溪流

还要考虑到这只是两个tar进程 - 并且无论您的文件数量如何,都不会改变。

tar | tar

tar正如您所希望的那样进行优化。这永远不会出现参数计数问题或失控的子进程。这只是甲>乙完毕。

论点

我在这里使用两个tar进程之间组合的 7 个不同的参数。最重要的首先列出在这里:

-标准输出/标准输入- 这表明tar它将流式传输其输入或输出stdin/stdout它将根据是否正在构建或提取档案来正确解释。

-c创造- 这告诉tar我们建立档案。下一个参数tar预期是......

-f文件- 我们指定tar将使用file对象而不是磁带设备或其他设备。如上所述,它将使用的文件是stdin/stdout- 换句话说,我们的|pipe

./*所有 $PWD/文件- 这里没有太多解释,除了存档参数是第一位的,所以-然后./*

|pipe...而在...的另一边

-C改变目录- 这表明tar它需要在执行任何其他操作之前更改为我指定的目录,因此在cd ../test2提取之前有效。

--transform='s/ed/EXPR/'- 正如已经提到的,这完成了重命名。但文档表明它可以采用任何sed表达式 或//flag.

-x提炼-tar更改目标目录并收到重命名指令后,我们指示它开始从存档文件中将所有文件提取到当前目录中-f - |pipe。没有什么神秘的。

答案4

在 zsh 中,将以下行放入您的.zshrc:

autoload -U zmv
alias zmv='noglob zmv'
alias zcp='zmv -C'
alias zln='zmv -L'

然后,在命令行上,你可以跑

zcp 'ABC(.*)' 'DEF$1'

或者简单地

zcp -W ABC.* DEF.*

在另一个 shell 中,只要安装了 zsh:

zsh -c 'autoload zmv; noglob zmv -CW ABC.* DEF.*'

相关内容