我試圖使用該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/bash
version 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
有一個陷阱和/或上的關鍵字find
。or
適用於以下所有參數,包括操作(-ls
在您的範例中)。不含(或附加)and
的表達式依讀取順序計算,最後停止為 false。沒有。or
and
implicit ()
所以這個指令的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-BUGS
find 線上說明頁 的 部分。