2010-03-11 47 views
30

我使用的是找到一個任務,我注意到,當我做這樣的事情:爲什麼在find命令中使用dirname會爲每個匹配提供點?

find `pwd` -name "file.ext" -exec echo $(dirname {}) \; 

它會給你點只爲每場比賽。當您在該命令中用dirname替換爲basename時,您將獲得完整的路徑名。我在這裏搞了些什麼,或者是這種預期的行爲?我習慣basename給你的文件名稱(在這種情況下file.ext)和dirname給你的路徑的其餘部分。

回答

24

請看下面的代碼:

#!/bin/sh 
set -x 
find `pwd` -name "file.ext" -exec echo $(dirname {}) \; 

set -x展示瞭如何擴建工程和最後的命令是什麼。運行時,它會產生以下輸出:

++ pwd 
++ dirname '{}' 
+ find /home/kibab -name file.ext -exec echo . ';' 

因此,首先擴展的是pwd。其次是$(dirname {})。這兩個命令的結果將被放入find命令中。因此,你告訴找到-exec echo .,所以你看到了預期的輸出。

當你替換basenamedirname,擴張仍然需要的地方,但擴張的結果是不同的:

  1. pwd擴展到當前路徑。在我上面的例子中,結果是/home/kibab
  2. basename {}被執行。該命令的結果是{}
  3. find命令在執行上述替換操作後執行。執行最後的命令如下:

    find /home/kibab -name '*.png' -exec echo '{}' ';'

在檢查上面的命令,你會發現,命令現在簡單地附和任何文件被發現的。

也許你想要這樣的東西?

find `pwd` -name "file.ext" -printf "%f\n" 
+0

@馬丁 - 好一點,解釋補充說。 – 2010-03-11 23:19:04

+0

這幫了一大筆錢。我不知道設置-x,並且我使用basename/dirname的唯一上下文是當我將它設置爲變量時。 – temp2290 2010-03-12 15:29:14

+0

你可能想看看'set -v'和一些其他選項。祝你好運。 – 2010-03-12 16:33:00

4

我不知道爲什麼你得到,但試試這個:

find `pwd` -name file.ext |xargs -l1 dirname 
+0

這實際上有幫助,但我必須用大寫字母替換小寫的'l'。爲什麼這個按預期工作,但是'... | xargs dirname'不? – 2017-05-22 15:42:08

0

這是因爲相對於它從搜索路徑find打印路徑。如果您從/嘗試此搜索,則會爲每個路徑獲取「pwd \」。

4

$(dirname {})在被傳遞給find之前由shell評估。此評估的結果爲.,因此您只要告知find就可以爲其找到的每個文件執行echo .

basename {}的計算結果爲{},所以用$(basename {})$(dirname {})取代,find將對於每個文件執行echo {}。這會導致每個文件的全名被回顯。

如果你想輸出的dirname每個文件中找到的結果,你可以省略echo

find `pwd` -name "file.ext" -exec dirname {} \; 
8

你不必調用目錄名稱()對於找到的每個文件。與GNU找到,你可以使用-printf和更快的這樣

find /path -type f -iname "*.ext" -printf "%h\n" 
17

所以問題是,$(...)或`...`啓動一個新的外殼,更換之前。

考慮使用bash -c:

$ find . -name '*.PNG' -exec bash -c 'git mv {} $(dirname {})/$(basename {} .PNG)48.png' \; 

一個重命名的Git回購任何圖標,更標準的形式。

這裏{}在執行任何事情之前被替換,所以問題沒有了。

對於那個例子,TMTOWTDI,但我儘量保持它簡單,所以你可以開始任何你真正需要做的事情。

2

它向您顯示點,因爲在命令實際執行之前評估流程替換。所以你必須將你的命令傳遞給單獨的shell實例。

至於解決方法,請使用以下語法:

find $PWD -name "file.ext" -exec sh -c 'echo $(dirname {})' ';' 

但是打印或在每個目錄執行的東西最簡單的方法是-execdir,如:

find . -name "file.ext" -execdir pwd ';' 
+0

這是唯一適合我的答案! – Leonmax 2018-03-04 05:28:06

相關問題