sle*_*ica 50 bash grep escaping command-line-interface
grep从命令行使用时不能输入"原始"字符串,因为某些字符需要转义才能被视为文字.例如:
$ grep '(hello|bye)' # WON'T MATCH 'hello'
$ grep '\(hello\|bye\)' # GOOD, BUT QUICKLY BECOMES UNREADABLE
Run Code Online (Sandbox Code Playgroud)
我printf用来自动转义字符串:
$ printf '%q' '(some|group)\n'
\(some\|group\)\\n
Run Code Online (Sandbox Code Playgroud)
这会生成字符串的bash-escaped版本,并且使用反引号,可以很容易地将其传递给grep调用:
$ grep `printf '%q' '(a|b|c)'`
Run Code Online (Sandbox Code Playgroud)
但是,它显然不适用于此:输出中的某些字符不会被转义,而有些则不必要.例如:
$ printf '%q' '(^#)'
\(\^#\)
Run Code Online (Sandbox Code Playgroud)
该^传递给角色时,不应该逃脱grep.
是否有一个cli工具,它接受一个原始字符串并返回一个bash-escaped版本的字符串,可以直接用作grep的模式?如果没有,我怎么能用纯粹的bash来实现呢?
eph*_*ent 46
如果要搜索确切的字符串,
grep -F '(some|group)\n' ...
Run Code Online (Sandbox Code Playgroud)
-F告诉grep我们将模式视为正则,没有解释为正则表达式.
(这通常也是可用的fgrep.)
tri*_*eee 23
如果您尝试grep使用扩展正则表达式语法,那么使用grep -E(aka egrep)的方法.您还应该了解grep -F(又名fgrep)和更新版本的GNU Coreutils grep -P.
背景:原版grep有一组相当小的正则表达式算子; 这是Ken Thompson最初的正则表达式实现.后来开发了具有扩展曲目的新版本,并且出于兼容性原因,获得了不同的名称.使用GNU时grep,只有一个二进制文件,如果调用as grep,则理解传统的基本RE语法,如果调用,则理解ERE egrep.一些构造egrep可以grep通过使用反斜杠转义来引入特殊含义.
随后,Perl编程语言进一步扩展了形式主义; 这种正则表达式方言似乎也是大多数新人错误地期望grep得到的支持.有grep -P,它确实; 但目前尚未在所有平台上广泛支持.
因此,grep以下字符具有特殊含义:^$[]*.\
在egrep,以下字符也有特殊含义:()|+?{}.(用于重复的括号都不在原始egrep)的分组圆括号也能够与反向引用\1,\2等等.
在许多版本中grep,您可以egrep通过在egrep特殊项之前加一个反斜杠来获得行为.还有一些特殊的序列\<\>.
在Perl中,\w \s \d引入了大量额外的转义.在Perl 5中,正则表达式工具大大扩展,具有非贪婪匹配*? +?等,非分组括号(?:...),前瞻,后观等.
...话虽如此,如果您确实想要将egrep正则表达式转换为grep正则表达式而不调用任何外部进程,请尝试${regex/pattern/substitution}使用每个egrep特殊字符; 但要认识到这不能正确处理字符类,否定字符类或反斜杠转义.
Ric*_*lli 21
当我使用grep -E和用户提供的字符串时,我用它来逃避它们
ere_quote() {
sed 's/[]\.|$(){}?+*^]/\\&/g' <<< "$*"
}
Run Code Online (Sandbox Code Playgroud)
示例运行
ere_quote ' \ $ [ ] ( ) { } | ^ . ? + *'
# output
# \\ \$ \[ \] \( \) \{ \} \| \^ \. \? \+ \*
Run Code Online (Sandbox Code Playgroud)
这样,您可以安全地在正则表达式中插入带引号的字符串.
例如,如果你想找到以用户内容开头的每一行,用户提供有趣的字符串.*
userdata=".*"
grep -E -- "^$(ere_quote "$userdata")" <<< ".*hello"
# if you have colors in grep you'll see only ".*" in red
Run Code Online (Sandbox Code Playgroud)
我认为以前的答案并不完整,因为他们错过了一件重要的事情,即以破折号 (-) 开头的字符串。因此,尽管这将无法正常工作:
echo "A-B-C" | grep -F "-B-"
Run Code Online (Sandbox Code Playgroud)
这将:
echo "A-B-C" | grep -F -- "-B-"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35916 次 |
| 最近记录: |