查找操作不適用於特定搜尋

查找操作不適用於特定搜尋

我試圖使用該find命令列出一組特定文件的大小,但沒有任何輸出。我使用的命令是:

find POD -type f -name *.mp3 -or -name *.ogg -ls

不會產生任何輸出。儘管:

find POD -type f -name *.mp3 -or -name *.ogg

確實產生輸出,我也嘗試過以下操作:

-printf "%p %k KB\n"
-exec ls -ls '{}' \;
-print0

但所有這些都沒有輸出。當我以不同的表達方式使用這些操作中的任何一個時,例如:

find . -maxdepth 1 -type f -printf "%p %k KB\n"

我也得到了預期的輸出。有人知道問題是什麼嗎?我在跑:

Linux irimi 3.10.37-1-MANJARO #1 SMP Mon Apr 14 20:56:29 UTC 2014 x86_64 GNU/Linux

又稱最新的 Manjaro Linux 發行版。我使用的外殼是:/bin/bashversion 4.3.8(1)-release

SHELLOPTS我的環境變數的內容是:

braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

我的BASHOPTS環境變數是:

cdspell:checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:hostcomplete:interactive_comments:nocaseglob:progcomp:promptvars:sourcepath

再次,我們將非常感謝任何有關嘗試調試此問題的幫助。

答案1

有一個陷阱和/或上的關鍵字findor適用於以下所有參數,包括操作(-ls在您的範例中)。不含(或附加)and的表達式依讀取順序計算,最後停止為 false。沒有。orandimplicit ()

所以這個指令的find POD -type f -name *.mp3 -or -name *.ogg -ls意思是,

  • 搜尋(從 POD 目錄開始)檔案 --- 如果沒有找到檔案:停止
  • else(找到文件)檢查模式匹配*.mp3 --- 如果模式匹配:停止! (因為OR從這裡應用並且僅當前一個命令失敗時才應用(但僅是前一個命令,而不是前一組命令)

並且因為您在命令列中添加了一條執行語句 ( -ls, -exec, -print....) ,所以沒有隱式-print命令,因此如果1) 1) 的所有條件都為真(文件和模式匹配),則無需執行任何操作。如果刪除最後一個,則每個條件分支的結尾-ls都會有一個隱式分佈。-print

  • 否則,如果模式不匹配,則搜尋與該模式匹配的任何內容(檔案/目錄)*.ogg並列出它們(這-ls不是條件命令,僅當前面的命令/測試“模式為真”時才會執行*.ogg。但由於1), 2) 僅針對非 mp3 文件進行評估,如果您沒有.ogg文件,則看不到任何內容。

解決方案1 在每個邏輯分支中重複執行命令

   find POD -type f -name "*.mp3" -ls -or -name "*.ogg" -ls

解決方案2添加(受外殼保護的)括號

   find POD -type f \( -name "*.mp3" -ls -or -name "*.ogg" \) -ls

筆記 您應該保護模式以避免目前目錄中的 shell 模式評估。

答案2

我認為這是因為評估順序(缺乏明確的優先順序),例如如果

-name '*.mp3' -o -name '*.ogg' -ls

那麼如果-name '*.ogg'評估結果為 false,ls則不執行該操作。您可以透過使用括號對 OR 表達式進行分組來獲得您期望的行為 - 例如,如果

$ ls tests
file1.mp3  file2.mp3  file3.mp3

然後

$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
tests/file3.mp3
tests/file1.mp3
tests/file2.mp3

然而

$ find tests -name '*.mp3' -o -name '*.ogg' -print

不產生輸出。注意

$ find tests -name '*.mp3' -o -name '*.ogg'

是一種特殊情況,因為它被隱式地視為

$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print

另請注意,最好在find命令中引用或轉義 shell 全域變量,以防止 shell 擴展它們 - 請參閱NON-BUGSfind 線上說明頁 的 部分。

相關內容