GNU 标准正则

GUN 对在正则表达式的功能进行了拓展,我们可以在 sedgrep -e 中使用正则表达式,支持的符号如下表所示。

符号 作用
. 任意单个字符
? 至多一个字符
* 任意个字符
+ 至少一个字符
{N} 前一个字符或字符组出现 N 次
{N, } 前一个字符或字符组至少出现 N 次
{N, M} 前一个字符或字符组至少出现 N 次,至多出现 M 次
- 用在中括号中表示范围
^ 用在中括号中表示反选,中括号外表示行首
$ 表示行尾
\< 匹配单词的开头
\> 匹配单词的结尾
(regexp) 字符组 regexp
\w 字母与数字,称为字符
\W 非字符,等价于 [^0-9a-zA-Z]
\s 空白字符,等价于 [[:space:]]
\S 匹配任何非空白字符,等价于 [^ \f\n\r\t\v]
regexp1\ regexp2 匹配表达式 1 或表达式 2,注意不能有空格
(.*)配合\N$ 表示与正则表达式中第N个用转义括号包裹的子表达式匹配,从左到右自动编号
[1-9][0-9]*  # 匹配一个正整数
abcdef  # 匹配 abcdef
a*b  # 匹配任意个 a 后接 b
a+b  # 匹配至少一个a 后接 b
a?b # 匹配至多一个 a 后接 b
.*  # 匹配所有字符串 包括空
.+  # 匹配至少有一个字符的字符串
^main\s*\(.*\)  #  开头main任意个空格(任意数量字符)
[a-zA-Z0-9]  # 等价于 [[:alnum:]]
[^0-9]  # 非数字
^\(.*\)-\1$  # 匹配 - 两侧一样的字符串 如 123-123
^.{2,4}A$  # 匹配 2 到 4 个任意字符开头后接 A 结尾
(a1){2}  # 字符组 a1 连续出现 2 次
[[:digit:]]|[[:alpha:]]  # 匹配数字或字母,等价于[[:alnum:]]
[[:digit:]][[:alpha:]]  # 匹配数字紧挨着字符

[success]技巧*+ 限定符都会尽可能多的匹配字符,但只要在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

[warning]警告:不能将限定符等与定位符 * + ? . 等一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。

grep 命令

grep :在文件中(全局)查找指定的正则表达式,并打印所有匹配的行。 egrep :支持更多正则表达式元字符( ? + { } | ( ) 不需要转义),等价于 grep -Efgrep :忽略所有元字符。

基础用法

grepGNU 提供的工具,用于在输入文件中搜索包含与给定模式列表匹配的行,其基础用法如下:

grep [选项] PATTERN FILE1 FILE2 ...

> grep root /etc/passwd  # 最基本用法
root:x:0:0:root:/root:/bin/bash

> grep -n ^r /etc/passwd  # 带行号
1:root:x:0:0:root:/root:/bin/bash  
30:rtkit:x:111:118:RealtimeKit,,,:/proc:/usr/sbin/nologin  
43:remilia:x:1000:1000:Remilia Scarlet,,,:/home/remilia:/bin/bash  
45:redis:x:124:135::/var/lib/redis:/usr/sbin/nologin  

> grep -v ^[a-z] /etc/passwd  # 反向查找 找不匹配的
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

> grep -c false /etc/passwd  # 统计匹配的行数
5

> grep -i ps ~/.bash* | grep -v history  # 忽略大小写 管道查询/home/remilia/.bashrc:HISTCONTROL=erasedups
/home/remilia/.bashrc:    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
/home/remilia/.bashrc:    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"

# -o 选项只显示匹配内容
> ifconfig | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'
127.0.0.1
255.0.0.0
192.168.0.104
255.255.255.0
192.168.0.255

# 显示匹配的上下文
> seq 5 | grep -C2 3  # 前后各两行
1
2
3
4
5
> seq 5 | grep -A2 3  # 后两行
3
4
5
> seq 5 | grep -B2 3  # 前两行
1
2
3

返回状态

0 :找到了指定的模式。 1 :没有找到指定的模式。 2 :没有找到文件。

> grep -q root /etc/passwd ; echo $?
0

配合正则表达式

> egrep 'NW' datafile  # 找带 NW 的行
> egrep 'NW|EA' d*  # 找带 NW 或 EA 的行
> egrep 's(h|u)'  # sh 或 su
> egrep 'sh|u'  # sh 或 u
> egrep '^n' datafile  # 查找以 n 开头的行
> egrep TB Savage datafile  # 注意这是从两个文件中找
> egrep 'TB Savage' datafile  # 这是从一个文件中找
> egrep ‘\..5’ datafile  # 例如 .65
> egrep '\.5‘ datafile  # 例如 .56
> egrep ’^[we]' datafile  # 以 w 或 e 开头的行
> egrep ‘\<[a-r].*n\>` datafile  # 以 [a-r] 开头并以 n 结尾的单词
> ifconfig | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'  # 点分十进制 ipv4 地址

字符类别

  • [:alnum:] Alphanumeric characters
  • [:alpha:] Alphabetic characters
  • [:blank:] Space and TAB characters
  • [:cntrl:] Control characters
  • [:digit:] Numeric characters
  • [:graph:] Characters that are both printable and visible (a space is printable but not visible, whereas an ‘a’ is both)
  • [:lower:] Lowercase alphabetic characters
  • [:print:] Printable characters (characters that are not control characters)
  • [:punct:] Punctuation characters (characters that are not letters, digits, control characters, or space characters)
  • [:space:] Space characters (these are: space, TAB, newline, carriage return, formfeed and vertical tab)
  • [:upper:] Uppercase alphabetic characters
  • [:xdigit:] Characters that are hexadecimal digits

results matching ""

    No results matching ""