将多个文件复制到多个目录

将多个文件复制到多个目录

我在复制不同目录中的许多文件时遇到问题。让我更好地解释一下:

假设我的目录中有以下内容:

$ ls
file1 file2 file3 file4 file5 dir1 dir2 dir3

我想用一个命令复制每个目录*中的每个文件*。我尝试过:

 echo dir{1..3} | xargs cp file{1..5} '{}' \;

我的目的是告诉 xargs 处理 echo 中的每个 dir* 并复制处理的输入中的所有文件,但此方法和类似方法不起作用。我想避免使用脚本,因为这是一个我必须对大约 20 个目录重复的任务,并且文件的名称略有不同,所以我更喜欢修改命令而不是脚本。

答案1

echo dir[1-3] | xargs -r -n1 cp file[1-5]

答案2

您在使用 xargs 时犯了一个小错误。如果没有 -n 参数,xargs 会将输入中的所有参数附加到命令中,并且echo dir{1..3}不会在每个条目之间添加必要的回车符,因此 xargs 会将结果视为一个参数。

xargs 有一个选项 -n 可以限制条目数量,您需要使用 \n 或 \0 作为分隔符列出目录:

find . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -n 1 cp file{1..5}

find 命令将查找当前目录中的所有目录,并使用 \0 作为分隔符(如果目录带有空格,则效果更好),而 xargs 使用 \0 作为分隔符,并且每次仅使用 1 个参数启动该命令。

答案3

如果它们确实有这样的名称,则类似以下内容应该有效:

#!/bin/bash
shopt -s nullglob
for dir in dir*/; do
    cp file* "$dir"
done

如果要将所有文件复制到所有目录(无论名称如何):

#!/bin/bash
shopt -s nullglob dotglob
for dir in */; do
    for file in *; do
        [[ -f $file ]] && cp "$file" "$dir"
    done
done

答案4

你快到了。您需要cp为每个目标目录运行单独的命令,因为cp只为每个源文件创建一份副本。的主要目的xargs是通过多个参数运行一个命令,但您可以使用该选项告诉它一次传递一个项目-n。也是;{} ;的语法find … -exec你不需要(也不能使用)它与xargs.

echo dir{1..3} | xargs -n 1 cp file{1..5}

请注意,只有当您的目录名不包含任何空格或任何字符时\'",这才有效,因为xargs无法判断这些字符是文件名的一部分,并且无法引用和分隔输入文件。不存在任何此类问题的另一种方法是使用 shell 循环:

for d in dirs{1..3}; do
  cp file{1..5} "$d"
done

所有这些都假设您可以通过名称轻松区分文件和目录。如果不能,可以通过/在末尾添加a来匹配目录;例如*/匹配当前目录中的所有目录,foo[0-9]*/匹配名称以foo数字开头的所有目录等。在大多数 shell 中没有类似的方法来仅匹配非目录,但是如果您将目录传递给cp不带任何参数来告诉它要进行递归复制,目录将被忽略并显示错误消息。

for d in */; do
  cp * "$d"
done

在 zsh 中,您可以使用全局限定符仅匹配某些文件类型。

for d in *(/); do
  cp *(.) $d
done

相关内容