如何仅复制匹配的文件,保留子目录

如何仅复制匹配的文件,保留子目录

有没有办法做到这一点:“如何从目录中复制文件子集,同时保留文件夹结构?”,但不使用 rsync?

是否可以仅使用 cp、find 和 grep 来完成?

我的 bash shell 非常有限(即它是 Windows 下的 git shell :( ),所以 rsync 不是一个选项。

我知道我可以获得 cygwin,但我想知道在这种有限的情况下我能做什么。

答案1

您可以使用tarcpiopax(如果其中任何一个可用) 复制某些文件,并根据需要创建目标目录。使用 GNU tar,要将当前目录下名为*.txt或的所有常规文件复制到 下的同一层次结构中:README.*../destination

find . -type f \( -name '*.txt' -o -name 'README.*' \) |
tar -cf - -T - |
tar -xf - -C ../destination

只需使用findcpmkdirshell,您就可以使用循环遍历所需的文件find并启动 shell 命令来复制每个文件。这虽然缓慢且麻烦,但非常便携。 shell 片段接收目标根目录为$0,源文件路径为$1;它根据需要创建目标目录树(请注意,下面的代码不会保留目录权限),然后复制文件。下面的代码片段适用于任何 POSIX 系统和大多数 BusyBox 安装。

find . -type f \( -name '*.txt' -o -name 'README.*' \) -exec sh -c '
  mkdir -p "$0/${1%/*}";
  cp -p "$1" "$0/$1"
' ../destination {} \;

您可以对sh调用进行分组;这有点复杂,但可能会更快。

find . -type f \( -name '*.txt' -o -name 'README.*' \) -exec sh -c '
  for x; do
    mkdir -p "$0/${x%/*}";
    cp -p "$x" "$0/$x";
  done
' ../destination {} +

如果你的 bash ≥4(我不知道 Git Bash 是否足够新),你不需要调用find,你可以使用**glob 模式递归到子目录。

shopt -s globstar extglob
for x in **/@(*.txt|README.*); do
  mkdir -p "../destination/${x%/*}"
  cp -p -- "$x" "../destination/$x"
done

答案2

你可以尝试这样的事情:

ls | grep 2 | xargs -n1 -t -i cp -R {} ../testdirTwo/{}

我在我的 Linux 上尝试过,它有效。请注意 cp 中的 -R 参数,如果您愿意,它用于递归。另请注意 -i 参数 o xargs,它会将其输出插入到您放置 {} 的位置。 -t 只是用于将命令回显到 stderr。

我的测试目录结构如下所示:

$ find .
.
./2
./2/f2
./1
./1/f1
./f1
./f2

相关内容