使用 cp 将单个文件复制到多个目录

使用 cp 将单个文件复制到多个目录

这个问题是我之前问题的续集,使用创建大量目录mkdir

我正在使用bash外壳。我使用以下命令创建了五十个目录,每个目录都以前缀“s”开头:

mkdir $(printf "s%02i " $(seq 1 50))

用零填充到第二个数字。也就是说,我获得的目录的形式为s01, s02, ..., s49, s50

现在我想使用cp将单个文件(例如,test.txt)复制到五十个目录中的每一个。是否可以通过与上述类似的方式来做到这一点?例如,以下内容会起作用吗?我对 Unix/Linux 比较陌生,所以我真的不想尝试这个,直到有人告诉我它是安全的。

cp test.txt $(printf "s%02i.txt " $(seq 1 50))

看看man的页面cp,它看起来并不cp支持像这样的多个目的地,但是:

NAME
       cp - copy files and directories

SYNOPSIS
       cp [OPTION]... [-T] SOURCE DEST
       cp [OPTION]... SOURCE... DIRECTORY
       cp [OPTION]... -t DIRECTORY SOURCE...

DESCRIPTION
       Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

       Mandatory  arguments  to  long  options are mandatory for short options
       too.

答案1

您还可以让 shell 通过for循环进行迭代。这是最基本的方法,不依赖于parallel或等外部工具xargs,我发现它最容易理解:

for name in $(printf "s%02i " $(seq 1 50)); do
    mkdir $name
    cp test.txt $name
done

还有一百万种其他的写法,例如:

for name in $(seq -w 1 50); do
    mkdir s$name
    cp test.txt s$name
done

如果您想在执行之前验证要执行的内容,您可以执行一些操作,例如在命令前面加上echo,这将打印该行而不是执行它:

for name in $(seq -w 1 50); do
    echo mkdir s$name
    echo cp test.txt s$name
done

输出:

mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.

答案2

如果您想使用命令的输出将文件复制到每个目录cp,您可以随时将其通过管道传输到xargs

printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt

不应该担心解析输出的安全性,因为您事先知道其格式和内容 - 在文件名中遇到元字符和空格的风险在这里并不是真正的问题。

或者,假设目录已经存在,您可以尝试以下操作:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}

或没有管道:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;

最后两个命令将查找当前目录中的所有文件以及cp test.txt它们。该-maxdepth 1选项将避免任何子目录接收该文件。请注意,'s[0-9][0-9]'匹配s后跟任何两个数字,这意味着如果由于某种原因您在s99cwd,它也会收到 的副本test.txt

答案3

根据这个:https://stackoverflow.com/questions/195655/how-to-copy-a-file-to-multiple-directories-using-the-gnu-cp-command无法将一个文件复制到多个目的地。检查链接,因为它显示了执行此操作的另一种方法。

答案4

你也可以使用 GNU平行线。假设您位于包含 text.txt 的目录中,并且您的 50 个目录位于/my/50dirs/path(例如/my/50dirs/path/s01/my/50dirs/path/s02),您将运行:

seq -w 01 50 | parallel -j1 cp text.txt /my/50dirs/path/s{}

相关内容