使用正则表达式和 Grep 转义 *

mon*_*ksy 7 shell grep quoting regular-expression

我有一个文件,其中包含以 2 颗星 (**) 开头的独特行。

但是,当我运行 grep 命令时

grep \*\* fileName 
Run Code Online (Sandbox Code Playgroud)

我得到了文件中的所有行。这是非常不寻常的,我认为不匹配的行不包含**。

我将如何逃避 ** 以找到正确的行?

slm*_*slm 9

您也可以通过指示grep要匹配的字符串是固定字符串来实现相同的目的。执行此操作的开关是-F--fixed-strings

-F, --fixed-strings
          Interpret  PATTERN  as  a  list of fixed strings, separated by 
          newlines, any of which is to be matched.  (-F is specified by
          POSIX.)
Run Code Online (Sandbox Code Playgroud)

所以像这样的事情会做到:

$ grep -F "**" somefile.txt
Run Code Online (Sandbox Code Playgroud)

例子

$ cat somefile.txt
** blah
blahblah
** hi
Run Code Online (Sandbox Code Playgroud)

Grepping 文件产生这个:

$ grep -F "**" somefile.txt
** blah
** hi
Run Code Online (Sandbox Code Playgroud)


Per*_*ulf 7

所以尝试:

egrep "^\*\*" YOUR_FILE
Run Code Online (Sandbox Code Playgroud)

不要忘记使用双引号。

注意:使用egrep代替grep.
如果你想使用grep使用grep -E

  • `egrep` 不是标准的。如果你想像 `awk` 一样扩展正则表达式,`grep -E` 就是你想要使用的。但是,`^\*\*` 在基本正则表达式和扩展正则表达式中是相同的。所以`grep '^\*\*'` 也一样好。 (5认同)

Sté*_*las 7

在:

grep \*\* fileName
Run Code Online (Sandbox Code Playgroud)

反斜杠用于转义*shell(其中*是通配符)。

什么grep接收作为其第二个参数是两个字符的字符串:**

作为正则表达式,这意味着任何(0 或更多)个星号字符,所以基本上它到处都匹配,因为它也匹配空字符串,这解释了为什么你得到文件的所有行。

因为*是特别的grep正则表达式,以及,你需要有逃避它。最好是使用单引号而不是反斜杠来转义*到 shell(因为单引号是强 shell 引号,可以转义除单引号字符本身之外的每个字符),并使用反斜杠转义*到 grep。双引号在这种情况下也可以工作,但要注意反斜杠对于双引号内的 shell 仍然是特殊的。

所以:

grep '\*\*' somefile.txt
Run Code Online (Sandbox Code Playgroud)

(使用*转义,因此它们不再是正则表达式运算符,而是被视为文字字符)将返回somefile.txt包含 2 个星形字符序列的行。如果您只想在行首找到它们,则必须使用锚定正则表达式运算符^

grep '^\*\*' somefile.txt
Run Code Online (Sandbox Code Playgroud)

另一种*不被视为正则表达式运算符的方法是使用字符范围:

grep '^[*][*]' somefile.txt
Run Code Online (Sandbox Code Playgroud)

指定两个星号的另一种方法是编写它:

grep '^\*\{2\}' somefile.txt
Run Code Online (Sandbox Code Playgroud)

(where \{is another regex operator) 如果您在将-E选项传递给时使用扩展的正则表达式则更容易阅读grep(避免,egrep因为它不是标准的):

grep -E '^\*{2}' somefile.txt
Run Code Online (Sandbox Code Playgroud)

(在扩展正则表达式中,{是正则表达式运算符)。