agg*_*877 6 grep options filenames arguments
我遇到了一个问题,当目录包含以破折号开头的文件时,grep 会感到困惑。
例如,我有一个名为“ ------.js
”的文件。当我做类似的事情时,grep somestring *
我收到错误:
grep: unrecognized option '------.js'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Run Code Online (Sandbox Code Playgroud)
这似乎是整个互联网都会问的那种问题,但我找不到任何东西。
我可以用类似的方法手动解决问题,find . | while read f; do grep MYSTRING "$f"; done
但我想知道是否有更简单/更强大的解决方案。
我正在运行 Arch Linux。
作为罗密欧答案的补充,请注意
grep pattern --whatever
Run Code Online (Sandbox Code Playgroud)
POSIX 需要在文件中查找模式--whatever
。那是因为在非选项参数之后不应识别任何选项(此处pattern
)。
grep
在这种情况下,GNU不符合 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
Run Code Online (Sandbox Code Playgroud)
(在那里,pattern
不是非选项参数,它作为参数传递给-e
选项,因此在此之后允许更多选项)。
因此,当您不能保证后面的内容不会以 a -
(或+
某些工具)开头时,将选项的结尾标记为 - 总是一个好主意:
grep -e pattern -- *.js
grep -- pattern *.js
Run Code Online (Sandbox Code Playgroud)
或使用:
grep -e pattern ./*.js
Run Code Online (Sandbox Code Playgroud)
(请注意,grep -- pattern *
如果有一个名为 的文件-
,则不会对您有帮助,whilegrep pattern ./*
会起作用。grep -e "$pattern"
应该使用,而不是grep "$pattern"
以防$pattern
它本身可能以 开头-
)。
上世纪 90 年代中期曾有人尝试bash
能够分辨getopt()
哪些参数(通常是由 glob 扩展产生的参数)不应被视为选项(通过_<pid>_GNU_nonoption_argv_flags_
环境变量),但由于它导致更多问题比它解决的要多。
您可以尝试告诉“参数结束”的 grep 选项
grep -- <string> <filename>
Run Code Online (Sandbox Code Playgroud)
这将通知 grep 忽略下一个破折号作为参数并将它们作为命令行中的下一个元素