关于linux:在find -exec中使用basename和full path

Using both basename and full path in find -exec

我正在用find today进行bash脚本编写世界的冒险。

假设我要将/home/mine/pictures的任何子目录中的任何png文件复制到/home/mine/png机会,并使用find和-exec将其重命名为"copy[basename]"。这将要求我在同一个exec命令中同时使用完整路径名和basename。我的问题是我不知道如何获取basename。(见下文)

1
find /home/mine -iname"*.png" -exec cp {} /home/mine/pngcoppies/copy{what_do_I_enter_here?} \;

注意:上面并不是我正在做的,但它是这个问题的一个基本例子,因此使用其他方法来实现相同目的的解决方法在这里并不真正适用。这个问题从根本上讲是关于find-exec及其对basename的使用。

事先谢谢!


要查看执行查找时发生了什么,只需键入set -xv。-X:在执行命令时打印命令及其参数。-V:读取时打印外壳输入行。

以下是我的资料:

1
find . -name"*.xml" -exec echo {} \;

给出输出:

1
2
./log.xml
./svnLog.xml

当我尝试的时候:

1
2
set -xv
find . -name"*.xml" -exec echo {} \;

我得到:

1
2
3
4
find . -name"*.xml" -exec echo {} \;
+ find . -name '*.xml' -exec echo '{}' ';'
./log.xml
./svnLog.xml

然后查找execute echo,传递找到的文件名而不是一般文件名:'{}'

但是当你在{}中添加一些东西时,如下所示:

1
2
3
4
find . -name"*.xml" -exec echo something{} \;
+ find . -name '*.xml' -exec echo 'something{}' ';'
something{}
something{}

在这里,echo对我拥有的2个XML文件执行了两次,由于没有更多的'{}'是exec的参数列表,所以它不会被替换。所以我们找到了每个文件的echo 'something{}'

为了解决这个问题,您可以考虑执行echo,将文件名作为参数传递给它,例如:

1
sh -xvc 'echo sothing/$0' filename

我们已经知道什么是-x-v-c是从后面的字符串中获取命令(man sh)

结果是:

1
2
3
4
5
sh -xvc 'echo somthing/$0' filename
+ sh -xvc 'echo somthing/$0' filename
echo somthing/$0
+ echo somthing/filename
sothing/filename

我在""之间使用了"EDOCX1"(9),这样,0美元就不会被当前的shell所扩展。用""试试,你会看到0美元的膨胀;)

因此,要返回到"问题",查找的格式应如下所示:

1
find . -name"*.xml" -exec sh -xvc 'echo sothing/$0' {} \;

我们将得到:

1
2
3
4
5
6
7
8
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

如我们所知,这个查找将执行shell cammand echo sothing/$0传递给它'{}'(由find找到的文件名替换),这样我们就得到所需的echo sothing/./log.xml

set +xv删除详细模式我们可以得到:

1
2
3
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之后添加shbash或您更喜欢shell),并让find将文件名作为副参数传递给它;

1
find /home/mine -iname"*.png" -exec sh -c 'cp $0 /home/mine/pngcoppies/copy/$0' {} \;

希望这能有所帮助,并原谅我的英语。


从人身上发现:"-execdir primary与-exec primary相同,但实用程序将从保存当前文件的目录执行。用字符串"`"""替换的文件名不合格。"

1
find /home/mine -iname"*.png" -execdir cp {} /home/mine/pngcoppies/copy{} \;


尝试如下操作:

1
2
find  /home/mine -iname"*.png" -printf"%P
" | xargs  -I % -n1 cp %  /home/mine/pngcoppies/copy%

要获取您使用的basename

1
basename $your_full_path

在basename之前获取该路径

1
dirname $your_full_path