要查看执行find命令时发生了什么,只需要键入set -xv
。
-x:在执行命令及其参数时打印它们。
-v:在读取shell输入行时打印它们。
这是我拥有的内容:
find . -name "*.xml" -exec echo {} \;
给出输出结果:
./log.xml
./svnLog.xml
当我尝试时:
set -xv
find . -name "*.xml" -exec echo {} \;
我理解为:
find . -name "*.xml" -exec echo {} \;
+ find . -name '*.xml' -exec echo '{}' ';'
./log.xml
./svnLog.xml
然后找到执行 echo 命令,传递找到的文件名而不是字面值:'{}'
但是当您像下面这样将一些内容添加到 {}
中时:
find . -name "*.xml" -exec echo something{} \;
+ find . -name '*.xml' -exec echo 'something{}' ';'
something{}
something{}
这里针对我拥有的2个XML文件执行了两次回显,由于'{}'
不再是exec
的参数列表中,它不会被替换。因此我们得到了每个找到的文件的echo 'something{}'
。
为了处理这个问题,你可以考虑像这样将文件名作为参数传递给echo:
sh -xvc 'echo sothing/$0' filename
我们已经知道什么是-x
和-v
。-c
的作用是从其后面的字符串中获取命令 (man sh
)。
所以结果是:
sh -xvc 'echo somthing/$0' filename
+ sh -xvc 'echo somthing/$0' filename
echo somthing/$0
+ echo somthing/filename
sothing/filename
我在单引号中使用 'echo somthing/$0
',以防止 $0 被当前 shell 展开。用双引号试试,你会看到 $0 被展开了 ;)
所以,回到你的 '问题',find 命令应该按以下格式进行格式化:
find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \;
然后我们将得到:
find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \;
+ find . -name '*.xml' -exec sh -xvc 'echo sothing/$0' '{}' ';'
echo sothing/$0
+ echo sothing/./log.xml
sothing/./log.xml
echo sothing/$0
+ echo sothing/./svnLog.xml
sothing/./svnLog.xml
正如我们现在所看到的,find命令将执行shell命令echo something/$0
,并传递'{}'
(由find找到的文件名替换)以便我们得到期望的echo something/./log.xml
set +xv
用于关闭详细模式,我们可以得到:
find . -name "*.xml" -exec sh -c 'echo "cp $0 someWhereElse/$0"' {} \;
cp ./log.xml someWhereElse/./log.xml
cp ./svnLog.xml someWhereElse/./svnLog.xml
所以在你的情况下,你只需要在子shell中执行复制操作(在exec之后添加sh
、bash
或您最喜欢的shell),并让find
将文件名作为参数传递给它;)
find /home/mine -iname "*.png" -exec sh -c 'cp $0 /home/mine/pngcoppies/copy/$0' {} \;
希望这可以帮到您,对我的英语表达请谅解。