有没有办法做到这一点:“如何从目录中复制文件子集,同时保留文件夹结构?”,但不使用 rsync?
是否可以仅使用 cp、find 和 grep 来完成?
我的 bash shell 非常有限(即它是 Windows 下的 git shell :( ),所以 rsync 不是一个选项。
我知道我可以获得 cygwin,但我想知道在这种有限的情况下我能做什么。
答案1
您可以使用tar
或cpio
或pax
(如果其中任何一个可用) 复制某些文件,并根据需要创建目标目录。使用 GNU tar,要将当前目录下名为*.txt
或的所有常规文件复制到 下的同一层次结构中:README.*
../destination
find . -type f \( -name '*.txt' -o -name 'README.*' \) |
tar -cf - -T - |
tar -xf - -C ../destination
只需使用find
、cp
和mkdir
shell,您就可以使用循环遍历所需的文件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