在find -exec中同时使用基本名和完整路径

问题描述 投票:7回答:5

我今天在寻找bash脚本的世界中冒险。

说我想将/ home / mine / Pictures的任何子目录中的任何png文件复制到/ home / mine / pngcoppies,并使用find和-exec将其重命名为“ copy [basename]”。这将要求我在同一exec命令中同时使用完整路径名和基本名。我的问题是我不知道如何获取基本名称。 (见下文)

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

注:上面的内容实际上并不是我正在做的事情,但这只是问题的基本示例,因此使用其他方法达到相同目的的解决方法在这里实际上并不适用。从根本上来说,问题是关于find -exec及其对基名的使用。

提前感谢!

linux find filenames rename
5个回答
12
投票

要查看执行查找时的情况,只需键入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

然后找到执行回显,将找到的文件名而不是原始文件名传递给'{}'

但是当您向{}中添加如下内容时:

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

这里回显对于我拥有的2个xml文件执行了两次,并且由于没有更多'{}'是exec的参数列表,因此不会替换它。因此我们为找到的每个文件获取了echo 'something{}'

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

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的expantion;)

所以要回到您的“问题”,查找结果应采用以下格式:

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

正如我们所看到的,发现将执行传递给它的壳cammandecho sothing/$0'{}'(由find找到的文件名代替,所以我们得到了所需的echo sothing/./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中执行复制(在执行后添加shbash或您喜欢的shell),然后让find将文件名作为参数传递给它;)

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

希望这会有所帮助,并且能使我的英语满意。


12
投票

从人中发现:““ -execdir主目录与-exec主目录相同,不同之处在于将从包含当前文件的目录中执行实用程序。用字符串“ {}”代替的文件名不合格。”

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

1
投票

尝试这样的事情:

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

0
投票

要获取您使用的基本名称

basename $your_full_path

要在基本名称之前获得该路径

dirname $your_full_path

0
投票

您需要结合前两个答案

我将带有[]的目录中的所有内容拖到另一个目录中>

find . -type f -exec sh -c 'tail -n 1000 $0 >../tail1000/$0.tail' {} \;

第一个答案给出

cp ./log.xml someWhereElse/./log.xml

或我的tail命令

find . -type f -exec sh -c 'tail -n 1000 $0 >../tail1000/$0.tail' {} \;

tail -n 1000 ./filenane > ../tail1000/./filenane.tail

这出奇地起作用,但看起来不像是一条不错的路径,我希望在某些情况下,路径/./morepath在某些命令下会执行某些意外操作。

结合答案给出

find . -type f -execdir sh -c 'tail -n 1000 $0 >../tail1000/$0.tail' {} \;

执行

tail -n 1000 filenane > ../tail1000/filenane.tail

并且看起来更有可能给出预期的结果。

© www.soinside.com 2019 - 2024. All rights reserved.