由于应用程序特定的原因,我需要将整个父目录复制到子目录中。例如,
cp -r ../ tmp/
这样做的问题是它陷入了无限循环,一遍又一遍地递归复制 tmp/ 的内容。
有很多方法可以解决这个问题,比如压缩目录并将其解压到 tmp 中,但我想知道是否有任何特别优雅/unixy 的解决方案。
(注:我使用的是 Apple OS/X)。
答案1
如果从父目录开始,则可以使用find
GNU来执行此操作cp
。假设您当前所在的目录(包含 的目录tmp
)名为folder
,并且该目录tmp
为空,您可以运行
cd ..
find . -path ./folder/tmp -prune -o -type f -exec cp --parents -t folder/tmp {} +
这要求 find 列出下面的所有内容.
(这是你的旧的..
),如果它匹配则排除它./folder/tmp
,否则如果它是一个文件,则将其传递给cp
选项--parents
(它告诉cp
重建源层次结构)。
如果tmp
已经有还需要复制的文件,则以下变体稍微少一点 Unix-y (因为它使用moreutils
' sponge
)但避免跳过以下内容tmp
:
cd ..
find . -type f -print0 | sponge | xargs -0 cp --parents -t folder/tmp
sponge
您可以通过保存要复制到其他位置的文件中的文件列表来避免使用(但随后事情会变得不太优雅):
cd ..
find . -type f -print0 > /tmp/filelist
xargs -0 cp --parents -t folder/tmp < /tmp/filelist
rm /tmp/filelist
cp
您可以通过使用以下方式来避免对 GNU 的要求cpio
:
cd ..
find . -type f -print0 > /tmp/filelist
cpio -pmd0 folder/tmp < /tmp/filelist
rm /tmp/filelist
或者
cd ..
find . -type f -print0 | sponge | cpio -pmd0 folder/tmp
如果tmp
为空,您还可以避免以下要求moreutils
:
cd ..
find . -path ./folder/tmp -prune -o -type f -print0 | cpio -pmd0 folder/tmp
答案2
对于交互式使用,我对 mv 的类似情况进行了修改:
cd ..
mv * tmp
mv: cannot move ‘tmp’ to a subdirectory of itself, ‘tmp/tmp’
忽略该错误,其他所有内容都已移动:-P。与 cp 的工作原理不太一样,它会创建一个空的 tmp/tmp,这可能不是您想要的。
答案3
使用pax
, 复制.
到subdir/tmp
, 跳过subdir/tmp
:
mkdir -p subdir/tmp &&
pax -rws'|^\./subdir/tmp/.*||' . subdir/tmp
或者,您可以执行以下操作:
mkdir -p subdir/tmp/subdir &&
ln -s tmp subdir/tmp/subdir/tmp &&
cp -a . subdir/tmp
subdir/tmp/subdir/tmp
那么它就是一个指向自身的符号链接,将cp
无法在其下创建任何内容。如果需要,您可以稍后将其替换为空目录。