find -exec cp 的问题

find -exec cp 的问题

考虑这个例子:

touch test0
touch timestamp
touch test1
sudo find /var/www/import -iname 'test*' -newer timestamp -exec cp {} new \;

它实际上复制了文件 test1,但它返回消息:

cp: `/var/www/import/new/test1' and `new/test1' are the same file

我究竟做错了什么?

第二个问题,我可以在这个命令中使用“+”,以便将文件复制到单个“包”中吗?有数千个文件!

答案1

我究竟做错了什么?

没关系。find找到已复制的文件new并尝试再次复制它们,因此会显示警告消息。

我可以在此命令中使用“+”,以便将文件复制到单个“包”中吗?有数千个文件!

是的,但是你需要这样修改你的命令:

find /var/www/import -iname 'test*' -newer timestamp -exec cp -t new {} +

因为{}在这种情况下必须位于 exec 语句的末尾。

答案2

echo在之前添加一个cp,你会看到它正在做

cp new/test1 new
cp test1 new

这是因为find它不仅查找当前目录,还查找所有子目录。

备择方案:

告诉find不要查看子目录:

find /var/www/import -maxdepth 1 \
    -iname 'test*' -newer timestamp -exec cp {} new \;

告诉find忽略new子目录:

find /var/www/import -type d -name new -prune -o \
    -iname 'test*' -newer timestamp -exec cp {} new \;

将文件复制到以下目录之外/var/www/import

find /var/www/import \
    -iname 'test*' -newer timestamp -exec cp {} /var/www/import.new \;

但如果您有子目录,您最终将丢失所有具有相同名称的文件。

例如,如果你有

test0
test1
scripts/test1

那么你最终会得到

test0
test1
new/test1
scripts/test1

哪个test1被复制到new

有几种方法可以处理这个问题,但我能想到的最简单、最有效的方法是使用cp --parents

cd /var/www/import
find . -type d -name new -prune -o \
    -type f -iname 'test*' -newer timestamp -exec cp --parents {} new \;

那会给你

test0
test1
new/test1
new/scripts/test1
scripts/test1

Rush已经回答了你问题的第二部分,我就不再重复了。

相关内容