unix 从所有子目录复制具有特定扩展名的所有文件,并保留子目录的结构

jyztefdp  于 2022-12-03  发布在  Unix
关注(0)|答案(2)|浏览(184)

如何将所有目录和子目录中的特定文件复制到新目录,同时保留原始子目录结构?
answer

find . -name \*.xls -exec cp {} newDir \;

解决了从同一目录newDir的所有子目录复制所有xls文件的问题。这不是我想要的。
如果xls文件位于:/s1/s2/,则应将其复制到newDir/s1/s2
会将所有文件夹和子文件夹中的所有文件复制到新文件夹中,但原始文件结构会丢失。所有内容都将被复制到同一个新文件夹中,并在其上重叠。

tag5nh1u

tag5nh1u1#

您可以尝试:

find . -type f -name '*.xls' -exec sh -c \
'd="newDir/${1%/*}"; mkdir -p "$d" && cp "$1" "$d"' sh {} \;

这会将d="newDir/${1%/*}"; mkdir -p "$d" && cp "$1" "$d" shell脚本应用于所有xls文件,也就是说,首先创建目标目录,然后将文件复制到目标位置。
如果您有很多文件和性能问题,您可以尝试优化一点:

find . -type f -name '*.xls' -exec sh -c \
'for f in "$@"; do d="newDir/${f%/*}"; mkdir -p "$d" && cp "$f" "$d"; done' sh {} +

第二个版本通过批处理来处理文件,因此生成的shell较少。

js5cn81o

js5cn81o2#

这应该做到:

# Ensure that newDir exists and is empty. Omit this step if you
# don't want it.
[[ -d newDir ]] && rm -r newDir && mkdir newDir

# Copy the xls files.
rsync -a --include='**/*.xls'  --include='*/' --exclude='*' . newDir

这里的技巧是 includeexclude 的组合。默认情况下,rsync复制其源目录下的所有内容(在本例中为.)。我们通过排除 * 所有内容 * 来改变这一点,但同时 * 包括 * xls文件。
在你的例子中,newDir 本身就是你的工作目录的子目录,因此是目录树的一部分,我会重新考虑这个决定。
注意:这不仅会复制名称以.xls结尾的目录,而且会重新创建源树的整个目录结构(即使其中没有xls文件),并只使用xls文件填充它。

相关问题