smc*_*smc 1 shell grep bash zsh
我在文本文件中有以下文本
$ cat test
20180618:
20180619:
20180620:
20180621:
20180622:
20180623:
20180624:
Run Code Online (Sandbox Code Playgroud)
我试图用下面的数字范围进行 grep,
$ grep 201806{19..21} test
grep: 20180619: No such file or directory
grep: 20180620: No such file or directory
grep: 20180621: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我在 ZSH 和 bash 上都遇到了上述错误。似乎 grep 将搜索字符串作为文件。
我试过另一种方式:
$ grep 201806* test
zsh: no matches found: 201806*
Run Code Online (Sandbox Code Playgroud)
我只在 ZSH 上收到该错误。*在 ZSH 中使用的正确方法是什么,如何告诉 grep 到 grep 的数字范围?
是的,默认情况下grep仅将其第一个参数视为正则表达式。
这意味着
grep {1..9} file
Run Code Online (Sandbox Code Playgroud)
扩展到
grep 1 2 3 4 5 6 7 8 9 file
Run Code Online (Sandbox Code Playgroud)
将调用grepwith1作为表达式以在其他操作数中匹配,并且这些其他操作数应为文件名。
你的另一个命令:
grep 201806* test
Run Code Online (Sandbox Code Playgroud)
这将尝试匹配201806*为文件名通配模式。201806当前目录中没有名称以开头的文件,因此zshshell 无法展开模式并显示错误消息no matches found。
在其他类似 Bourne 的 shell 中,如果模式没有匹配任何文件名,它将保持未扩展状态并用作带有grep. 表达式201806*作为正则表达式时,匹配20180后跟零个或多个6字符,例如2018066666.
相反,您可能想要构建一个正则表达式来匹配您的范围:
grep -E '201806(19|20|21)' test
Run Code Online (Sandbox Code Playgroud)
或者
grep -E '201806(19|2[01])' test
Run Code Online (Sandbox Code Playgroud)
的-E需要已经grep了解|在表达式(交替)(此交替使得它扩展正则表达式)。
您还可以从大括号扩展构造正则表达式:
set -- {19..21}
re=$( IFS='|'; printf '201806(%s)' "$*" )
grep -E "$re" test
Run Code Online (Sandbox Code Playgroud)
这将首先设置的位置参数$1,$2并且$3,在该范围的通缉编号。re然后将变量设置为201806(%s)whereprintf将替换%s为由 分隔的这些数字|。
该grep调用将201806(19|20|21)用作正则表达式。
| 归档时间: |
|
| 查看次数: |
9975 次 |
| 最近记录: |