所以......你已经得到了一个文件夹列表。也许在文本文件中?您没有提供示例,但您在评论中说不会有名称冲突。
一种选择是使用rsync
,它可作为大多数 Unix 和 Linux 版本的附加包使用。Rsync 基本上是一种高级复制工具——你为它提供一个或多个源和一个目标,它确保事情是同步的。它知道如何递归地复制事物,但不能告诉它将递归限制在特定的深度,因此以下将复制指定的每个项目到您的目标,但它会递归地这样做。
xargs -L 1 -J % rsync -vi -a % /path/to/target/ < sourcelist.txt
如果 sourcelist.txt 包含带有 的行/foo/bar/slurm
,则该slurm
目录将被完整复制到/path/to/target/slurm/
. 但这将包括包含在slurm
.
这几乎可以在任何 shell 中工作,而不仅仅是 bash。但是如果 sourcelist.txt 中的某一行包含空格或各种特殊字符,它将失败。因此,确保您的源(在命令行或 sourcelist.txt 中)格式正确非常重要。此外,如果源目录包含尾部斜杠,则 rsync 具有不同的行为,您应该阅读手册页并确定您想要的行为。
您可以在 sh 或 bash 中相当轻松地清理输入文件。例如:
#!/bin/sh
# Avoid commented lines...
grep -v '^[[:space:]]*#' sourcelist.txt | while read line; do
# Remove any trailing slash, just in case
source=${line%%/}
# make sure source exist before we try to copy it
if [ -d "$source" ]; then
rsync -vi -a "$source" /path/to/target/
fi
done
但这仍然使用 rsync 的-a
选项,它递归地复制东西。
我看不到单独使用 rsync 的方法。Rsync 没有-depth
选择,因为find
有。但我可以看到这样做分两遍——一次复制所有目录,一次复制每个目录中的文件。
所以我将举一个例子,并进一步假设文件夹名称不包含空格或换行符等特殊字符。 (这个很重要。)
首先,让我们对所有目录本身进行一次复制,而不是递归到它们:
xargs -L 1 -J % rsync -vi -d % /path/to/target/ < sourcelist.txt
该-d
选项创建在 sourcelist.txt 中指定的目录(如果存在)。
其次,让我们浏览一下来源列表,复制每个来源:
# Basic sanity checking on input...
grep -v '^[[:space:]]*#' sourcelist.txt | while read line; do
if [ -d "$line" ]; then
# Strip trailing slashes, as before
source=${line%%/}
# Grab the directory name from the source path
target=${source##*/}
rsync -vi -a "$source/" "/path/to/target/$target/"
fi
done
$source
注意rsync 行后面的斜杠。这会导致 rsync 复制目录的内容,而不是目录。
这一切有意义吗?是否符合您的要求?