Grep

grep 對帶有破折號的文件名感到困惑

  • February 6, 2022

當目錄包含以破折號開頭的文件時,我遇到了一個問題,即 grep 會感到困惑。

例如,我有一個名為 " ------.js" 的文件。當我做類似的事情時,grep somestring *我得到了錯誤:

grep: unrecognized option '------.js'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

這似乎是整個網際網路都會問的那種問題,但我找不到任何東西。

我可以手動解決問題,
find . | while read f; do grep MYSTRING "$f"; done
但我想知道是否有更簡單/更強大的解決方案。

我正在執行 Arch Linux。

作為羅密歐回答的補充,請注意

grep pattern --whatever

POSIX 要求在文件中查找模式。--whatever這是因為在非選項參數(此處pattern)之後不應辨識任何選項。

在那種情況下, GNUgrep不符合 POSIX。它可以通過將 POSIXLY_CORRECT 環境變數(具有任何值)傳遞到其環境中來使其兼容。

大多數 GNU 實用程序和使用 GNU 或getopt()/的兼容實現getopt_long()來解析命令行參數的實用程序就是這種情況。

有明顯的例外,例如env,在哪裡env VAR=x grep --version可以得到你的版本grep,而不是env. 另一個值得注意的例外是 GNU shell ( bash),其中解釋器及其任何內置函式都不接受非選項參數之後的選項。甚至它getopts也無法以 GNU 方式解析選項。

無論如何,如果你這樣做,POSIXLY_CORRECT 不會拯救你

grep -e pattern *.js

(那裡,pattern不是非選項參數,它作為參數傳遞給-e選項,因此之後允許更多選項)。

因此,當您不能保證後面的內容不會以 a -(或+某些工具)開頭時,用以下標記選項的結束總是一個好主意:

grep -e pattern -- *.js
grep -- pattern *.js

或使用:

grep -e pattern ./*.js

(請注意,grep -- pattern *如果有一個名為-, while的文件grep pattern ./*會起作用,這對您沒有幫助。grep -e "$pattern"應該使用而不是grep "$pattern"以防萬一$pattern本身可能以 開頭-)。

上世紀 90 年代中期曾有人嘗試bash判斷getopt()哪些參數(通常是由 glob 擴展產生的參數)不被視為選項(通過_<pid>_GNU_nonoption_argv_flags_環境變數),但由於它導致更多比它解決的問題。

引用自:https://unix.stackexchange.com/questions/364922