2013-10-01 40 views
7

我在今天發現了bash腳本世界中的冒險。在find -exec中同時使用基本名稱和完整路徑

假設我正在尋找將/ 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?} \; 

注:以上實際上不是我在做什麼,但它的問題的一個基本例子,因此使用其他一些方法解決方法來達到同樣的目的止跌」這裏真的適用。這個問題基本上是關於查找-exec及其基名的使用。

在此先感謝!

回答

9

看到的是,當你執行查找下去,只需要輸入set -xv
-x:打印命令及其參數作爲它們被執行
-v:打印外殼的輸入行讀

以下是我有:

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 

,然後找到執行回聲傳遞,而不是litteral找到的文件名:'{}'

但是當你添加一些東西到{}如下:

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

這裏echo 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 

正如我們看到的知道,找到的是要執行shell cammand echo sothing/$0傳遞給它'{}'(通過查找發現的文件名代替),所以我們得到想要的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 
你的情況

所以,你剛剛執行的一個子殼的副本(Exec之後添加shbash,或者你FAVORIT殼)讓find傳遞文件名作爲parapeter到它;)

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

希望這可以幫助,並execuse我要我的英語水平。

0

要獲得基本名稱使用

basename $your_full_path 

連接到基名

dirname $your_full_path 
+4

對不起,要求勺飼料,但我怎麼可以將這個應用到我的實例發現? – neanderslob

1

之前獲取路徑嘗試是這樣的:

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

從人發現: 「的 - execdir primary與-exec primary相同,只是將從目錄t執行實用程序帽子擁有當前文件。的字符串``{}「」取代文件名是沒有資格「

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