为什么“cp”在与“find”链接时抱怨相同的文件?

Isa*_*aac 7 command-line bash scripts find cp

我有一个find如下的命令列出了匹配的文件:

$ find . -type f -name "*.txt"

./level2/file2.txt
./level2/level3/file3.txt
./level2/level3/level4/file4.txt
./level2/level3/level4/level5/file5.txt
./output.txt
Run Code Online (Sandbox Code Playgroud)

现在我尝试通过链接将每个列出的文件复制到特定文件夹exec

$ ls copy_here | wc -l
0

$ find . -type f -name "*.txt" -exec cp {} ./copy_here \;
cp: ./copy_here/file2.txt and ./copy_here/file2.txt are identical (not copied).
cp: ./copy_here/file3.txt and ./copy_here/file3.txt are identical (not copied).
cp: ./copy_here/file4.txt and ./copy_here/file4.txt are identical (not copied).
cp: ./copy_here/file5.txt and ./copy_here/file5.txt are identical (not copied).
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助分解执行顺序以帮助更好地理解执行流程吗?

fri*_*ppe 15

这是因为命令find正在做事。在您的情况下,首先find搜索您的levelX目录,找到.txt文件并将它们复制到./copy_here. (顺便说一句,您不应该依赖于发现事物的顺序find,因此这种错误可能会也可能不会发生。请参阅。)

问题是当findthen 到达 时copy_here,此时它包含之前复制的.txt文件。find找到这些文件并尝试将它们复制到同一目录,从而导致上述错误。

为了避免这种情况,您可以./copy_here从以下目录中排除该目录find

find -type f -name "*.txt" ! -path "./copy_here*" -exec cp {} ./copy_here \;
Run Code Online (Sandbox Code Playgroud)

(还有其他几种方法可以排除目录和模式)

或者告诉cp不要覆盖现有文件:

find -type f -name "*.txt" cp -n ./copy_here {} \;
Run Code Online (Sandbox Code Playgroud)