今天在学习正则表达式时发现,grep对正则表达式的解释和我想到的不同。
我本来打算用\<the\>来匹配the,但却没有匹配任何文本,上网也没有查到资料。
通过对于某一个文件的试验,我发现了原因:
在shell中使用grep的解析顺序是这样的:
1. shell首先会解析有没有元字符,如: grep p * 会检查当前目录中所有文件,并返回带有p的行,而且高亮显示p。
3. 遵循正则表达式的语法进行解析,在这时才真正开始解析正则表达式,也就是说这时\<the\>才会被理解成恰好匹配the这个字符串。
换句话说,如果要在shell中使用正则表达式,要先经过shell的解释(interpert),如果有shell中的元字符,而你又不想让shell解释他,那么你要先转义一次。
例如mastering_regex_note_log.txt这个文件:
$ cat mastering_regex_note_log.txt
返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
$ cat mastering_regex_note_log.txt | grep \<p29\>
不返回任何值
$ cat mastering_regex_note_log.txt | grep \\\<p29\\\>
或
$ cat mastering_regex_note_log.txt | grep '\<p29\>'
返回
9-18 p29
另外,如果shell不把某个字符当作特殊字符或不能解析,就会直接交给grep
cat mastering_regex_note_log.txt | grep .返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
cat mastering_regex_note_log.txt | grep \.同样返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
而cat mastering_regex_note_log.txt | grep \\.
不返回任何值,因为这时grep在文件中没有找到'.'这个字符。
cat mastering_regex_note_log.txt | grep \\.*返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
因为'.'这个字符出现了0次,所以匹配任何文本,但都不高亮显示
另一个例子是cat 1 | grep $,返回
this is $
cat 1 | grep \$,cat 1 | grep 同样返回
this is $
而cat 1 | grep \\$,cat 1 | grep \\\$和cat 1 | grep '\$'返回
this is $
和上面是一样的道理。
我本来打算用\<the\>来匹配the,但却没有匹配任何文本,上网也没有查到资料。
通过对于某一个文件的试验,我发现了原因:
在shell中使用grep的解析顺序是这样的:
1. shell首先会解析有没有元字符,如: grep p * 会检查当前目录中所有文件,并返回带有p的行,而且高亮显示p。
3. 遵循正则表达式的语法进行解析,在这时才真正开始解析正则表达式,也就是说这时\<the\>才会被理解成恰好匹配the这个字符串。
换句话说,如果要在shell中使用正则表达式,要先经过shell的解释(interpert),如果有shell中的元字符,而你又不想让shell解释他,那么你要先转义一次。
例如mastering_regex_note_log.txt这个文件:
$ cat mastering_regex_note_log.txt
返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
$ cat mastering_regex_note_log.txt | grep \<p29\>
不返回任何值
$ cat mastering_regex_note_log.txt | grep \\\<p29\\\>
或
$ cat mastering_regex_note_log.txt | grep '\<p29\>'
返回
9-18 p29
另外,如果shell不把某个字符当作特殊字符或不能解析,就会直接交给grep
cat mastering_regex_note_log.txt | grep .返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
cat mastering_regex_note_log.txt | grep \.同样返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
而cat mastering_regex_note_log.txt | grep \\.
不返回任何值,因为这时grep在文件中没有找到'.'这个字符。
cat mastering_regex_note_log.txt | grep \\.*返回
9-18 p29
9-18 p35
不要把^cat理解成匹配以cat开头的行,应该认为^cat匹配以c为一行的第一个字符,紧接着一个c,紧接着一个t的文本。
9-18 P37
9-19 P41
\
因为'.'这个字符出现了0次,所以匹配任何文本,但都不高亮显示
另一个例子是cat 1 | grep $,返回
this is $
cat 1 | grep \$,cat 1 | grep 同样返回
this is $
而cat 1 | grep \\$,cat 1 | grep \\\$和cat 1 | grep '\$'返回
this is $
和上面是一样的道理。