简体   繁体   English

Bash Perl正则表达式无法正确转义

[英]Bash perl regex not escaping properly

I have this command: 我有以下命令:

grep -PoRn '(?!.+?\.trigger[\(\s]+[\'\"])([a-zA-Z\:]+)(?>![\'\"])' .

But it throws up this: 但是它抛出了这个:

-bash: ![\'\"]: event not found

Why? 为什么? I have single quotes around my regex; 我的正则表达式有单引号。 I'm using -P for perl, I have escaped my single and double quotes, but nae luck. 我在Perl上使用-P ,我已经避免了单引号和双引号,但是运气不好。

Bash version is 4.2.25(1)-release on Ubuntu. Bash版本是Ubuntu上的4.2.25(1)-release版本。

Any ideas? 有任何想法吗? Cheers! 干杯!

This is happening because history expansion happens inside single quotes. 发生这种情况是因为历史记录扩展发生在单引号内。

You can get around this by using the $'' format: 您可以使用$''格式解决此问题:

grep -PoRn $'(?!.+?\.trigger[\(\s]+[\'\"])([a-zA-Z\:]+)(?>![\'\"])' .

From the bash man page: bash手册页:

   Words of the form $'string' are treated specially.  The word expands to
   string,  with backslash-escaped characters replaced as specified by the
   ANSI C standard.  Backslash escape sequences, if present,  are  decoded
   as follows:
          \a     alert (bell)
          \b     backspace
          \e
          \E     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \"     double quote
          \nnn   the  eight-bit  character  whose value is the octal value
                 nnn (one to three digits)
          \xHH   the eight-bit character whose value  is  the  hexadecimal
                 value HH (one or two hex digits)
          \uHHHH the  Unicode (ISO/IEC 10646) character whose value is the
                 hexadecimal value HHHH (one to four hex digits)
          \UHHHHHHHH
                 the Unicode (ISO/IEC 10646) character whose value is  the
                 hexadecimal value HHHHHHHH (one to eight hex digits)
          \cx    a control-x character

The ! ! is being treated as the beginning of a history expansion. 被视为历史扩展的开始。 You can turn this feature off temporarily with 您可以使用以下方法暂时关闭此功能

set +H  # Turn history expansion off
grep -PoRn '(?!.+?\.trigger[\(\s]+[\'\"])([a-zA-Z\:]+)(?>![\'\"])' .
set -H  # Turn history expansion back on

Rather than turning it off and on unconditionally, you can check the $- parameter to see if the H option is set: 您可以检查$-参数以查看是否设置了H选项,而不是无条件关闭和打开它:

[[ $- = *H* ]]; hist_on=$?   # Is history expansion enabled?
(( hist_on )) && set +H      # Turn it off if it is
grep ...
(( hist_on )) && set -H      # Turn it back on if it was

If you are able to run your command in a subshell, you can just turn history expansion off for the subshell; 如果您能够在子Shell中运行命令,则只需关闭该子Shell的历史记录扩展即可; the original setting in the current shell (on or off) will be unchanged. 当前外壳中的原始设置(打开或关闭)将保持不变。

( set +H; grep ... )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM