正则表达式

2.正则表达式

定义:它使用单个字符串来描述或匹配一系列符合某个句法规则的字符串。在很多文本编辑器或其它工具中,正则表达式通常用来检索和替换某个模式的文本内容。

其实正则表达式只是一种思想、一种方法。只要我们使用的工具支持这种方法,那么这个工具就可以处理正则表达试的字符串。常用的工具有grep、sed、awk等,其中grep、sed和awk都是对文本的行进行操作。

2.1 grep/egrep工具的使用

该命令的格式为:grep [-cnvABC] 'worf' filename,其常用的选项如下所示:

-c:表示打印符合要求的行数。

-i:表示忽略大小写。

-n:表示输出符合要求的行机器行号。

-v:表示打印不符合要求的行。

-A:后面跟一个数字(有无空格都可以),例如-A2表示打印符合要求的行以及下面两行。

-B:后面跟一个数字,例如-B2表示打印符合要求的行以及上面两行。

-C:后面跟一个数字,例如-C2表示打印符合要求的行以及上下各两行。

首先看看-A、-B和-C这3个选项的用法。

-A2会把包含halt的行以及这行下面的两行都打印出来:

root@localhost \~\]# grep -A2 'halt' /etc/passwd halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin

-B2:会把包含halt的行以及这行上面的两行都打印出来:

root@localhost \~\]# grep -B2 'halt' /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt

-C2会把包含halt的行以及上下各两行都打印出来:

root@localhost \~\]# grep -C2 'halt' /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin

2.1.1过滤出带有某个关键词的行,并输出行号

示例命令如下:

root@localhost \~\]# grep -n 'root' /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 10:operator:x:11:0:operator:/root:/sbin/nologin

2.1.2过滤出不带有某个关键词的行,并输出行号

示例命令如下:

root@localhost \~\]# grep -nv 'root' /etc/passwd 2:bin:x:1:1:bin:/bin:/sbin/nologin 3:daemon:x:2:2:daemon:/sbin:/sbin/nologin 4:adm:x:3:4:adm:/var/adm:/sbin/nologin 5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6:sync:x:5:0:sync:/sbin:/bin/sync 7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8:halt:x:7:0:halt:/sbin:/sbin/halt 9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 11:games:x:12:100:games:/usr/games:/sbin/nologin 12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13:nobody:x:99:99:Nobody:/:/sbin/nologin 14:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin 15:dbus:x:81:81:System message bus:/:/sbin/nologin 16:polkitd:x:999:998:User for polkitd:/:/sbin/nologin 17:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 18:postfix:x:89:89::/var/spool/postfix:/sbin/nologin 19:chrony:x:998:996::/var/lib/chrony:/sbin/nologin

2.1.3过滤出包含数字的行

示例命令如下:

root@localhost \~\]# grep '\[0-9\]' /etc/inittab # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5

2.1.4过滤出所有不包含数字的行

root@localhost \~\]# grep -v '\[0-9\]' /etc/inittab # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target # # systemd uses 'targets' instead of runlevels. By default, there are two main targets: # # # To view current default target, run: # systemctl get-default # # To set a default target, run: # systemctl set-default TARGET.target #

2.1.5过滤掉所有空行和以#开头的行

示例命令如下:

root@localhost \~\]# cat /etc/grep.txt aaaa bbb #ccc dddd \[root@localhost \~\]# grep -v '\^#' /etc/grep.txt \|grep -v '\^$' aaaa bbb dddd

正则表达式中,^表示行的开始,表示行的结尾,那么空行就可以用\^表示。如何打印出不以英文字母开头的行呢?举个例子:

root@localhost \~\]# cat /etc/grep.txt 2aaaa b1bb 123 #ccc 2222 dddd AAAAA 333 \[root@localhost \~\]# grep -v '\^\[a-zA-Z\]' /etc/grep.txt 2aaaa 123 #ccc 2222 333 \[root@localhost \~\]# grep '\^\[\^a-zA-Z\]' /etc/grep.txt 2aaaa 123 #ccc 2222 333 \[root@localhost \~\]# grep '\[\^a-zA-Z\]' /etc/grep.txt 2aaaa b1bb 123 #ccc 2222 333

\^字符\]表示除\[\]以外的字符。注意把\^写到括号里跟括号外是有区别的。前面提到过\[\]的应用,如果是数字就用\[0-9\]这样的形式(当遇到类似\[15\]的形式时表示只含有1或者5)。如果要过滤数字以及大小写字母,则要写成类似\[0-9a-zA-Z\]的形式。 #### **2.1.6过滤出任意一个字符和重复字符** 示例命令如下: > \[root@localhost \~\]# grep 'r.o' /etc/passwd > > root:x:0:0:root:/root:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin .表示任意一个字符。上海李忠,r.o表示把r与o之间有一个任意字符的行过滤出来。 > \[root@localhost \~\]# grep 'ooo\*' /etc/passwd > > root:x:0:0:root:/root:/bin/bash > > lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin > > mail:x:8:12:mail:/var/spool/mail:/sbin/nologin > > operator:x:11:0:operator:/root:/sbin/nologin > > postfix:x:89:89::/var/spool/postfix:/sbin/nologin \*表示零个或多个\*前面的字符。上例中,ooo\*表示oo、ooo、oooo或者更多的o。 > \[root@localhost \~\]# grep '.\*' /etc/passwd \|wc -l > > 19 \*表示零个或者多个任意字符,空行也包括在内,他会把/etc/passwd文件里面所有行都匹配到。 #### **2.1.7指定要过滤出的字符出现次数** 示例命令如下: > \[root@localhost \~\]# grep '0\\{2\\}' /etc/passwd > > games:x:12:100:games:/usr/games:/sbin/nologin 这里用到了符号{},其内部位数字,表示前面的字符要重复的次数。需要强调的是,{}左右都需要加上转义字符\\。另外,使用"{}"还可以表示一个范围,具体格式{n1,n2},其中n1\ \[root@localhost \~\]# vi /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa #### **2.1.8过滤出一个或多个指定的字符** 示例命令如下: > \[root@localhost \~\]# egrep 'o+' /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > \[root@localhost \~\]# egrep 'oo+' /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > \[root@localhost \~\]# egrep 'ooo+' /etc/grep.txt > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash 和grep不同的是,egrep使用的是符号+,他表示匹配1个或多个+前面的字符,这个"+"是不支持被grep直接使用的。包括上面的{},也是可以直接被egrep使用,而不用加\\转义。示例如下: > \[root@localhost \~\]# egrep 'o{2}' /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash #### **2.1.9过滤出零个或一个指定字符** 示例如下: > \[root@localhost \~\]# egrep 'o?' /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > > \[root@localhost \~\]# egrep 'ooo?' /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > \[root@localhost \~\]# egrep 'oooo?' /etc/grep.txt > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash #### **2.1.10过滤出字符串1或者字符串2** 示例命令如下: > \[root@localhost \~\]# egrep 'aaa\|111\|ooo' /etc/grep.txt > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa #### **2.1.11egrep中()的应用** 示例命令如下: > \[root@localhost \~\]# egrep 'r(oo\|at)o' /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash 这里用()表示一个整体,上例中会把包含rooo或者rato的行过滤出来,林外也可以吧()和其他符号组合在一起,例如(oo)+就表示1个或者多个oo。如下所示: > \[root@localhost \~\]# egrep '(oo)+' /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash ### **2.2sed工具的使用** 其实grep工具的功能还不够强大,它实现的只是查找功能,而不能把查找的能容替换。以前用vim操作文档的时候,可以查找也可以替换,但只限于在文本内部操作,而不能输出到屏幕上。sed工具以及后面要介绍的awk工具就能把替换的文本输出到屏幕上,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。 #### **2.2.1打印某行** sed的格式为:sed -n 'n'p filename ,单引号内的n是一个数字,表示第几行。-n选项的作用是只显示我们要打印的行,无关紧要的内容不显示。示例命令如下: > \[root@localhost \~\]# sed -n '2'p /etc/passwd > > bin:x:1:1:bin:/bin:/sbin/nologin 你可以去掉-n选项对比一下差异。要想把所有行都打印出来,可以使用命令sed -n '1,$'p filename,如下所示: > \[root@localhost \~\]# sed -n '1,$'p /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 当然我们也可以指定一个区间打印,如下所示: > \[root@localhost \~\]# sed -n '1,3'p /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin #### **2.2.2打印包含某个字母的字符串的行** 示例命令如下: > \[root@localhost \~\]# sed -n '/root/'p /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin 这种用法就类似于grep了,在grep中使用的特殊字符(如\^,$,.,\*等)同样也可以在sed中使用,如下所示: > \[root@localhost \~\]# sed -n '/\^1/'p /etc/grep.txt > > 1111111111111111111111111111111 > > \[root@localhost \~\]# sed -n '/in$/'p /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > \[root@localhost \~\]# sed -n '/r..o/'p /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > \[root@localhost \~\]# sed -n '/ooo\*/'p /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash sed命令加上-e选项可以实现多个行为,如下所示: > \[root@localhost \~\]# sed -e '1'p -e '/111/'p -n /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > 1111111111111111111111111111111 #### **2.2.3删除某些行** 示例命令如下: > \[root@localhost \~\]# sed '1'd /etc/grep.txt > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > > \[root@localhost \~\]# sed '1,3'd /etc/grep.txt > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > > \[root@localhost \~\]# sed '/oot/'d /etc/grep.txt > > rot:x:0:0:/rot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 这里参数d表示删除的动作,它不仅可以删除指定的单行以及多行,而且可以删除匹配某个字符的行,还可以删除从某一行开始到最后一行所有行。不过,这个操作仅仅是在显示器屏幕上并不显示这些行而已,文档还好好的。 #### **2.2.4替换字符或者字符串** 示例命令如下: > \[root@localhost \~\]# sed '1,2s/ot/to/g' /etc/grep.txt > > rto:x:0:0:/rto:/bin/bash > > operator:x:11:0:operator:/roto:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 上例中的参数s就表示替换的动作,参数g表示本行全局替换,如果不加g则只替换本行出现的第一个,这个用法其实和vi的替换大同小异。 除了可以使用/作为分隔符外,我们还可以使用其他特殊字符,例如#和@。如下所示: > \[root@localhost \~\]# sed 's#ot#to#g' /etc/grep.txt > > rto:x:0:0:/rto:/bin/bash > > operator:x:11:0:operator:/roto:/sbin/nologin > > operator:x:11:0:operator:/rooto:/sbin/nologin > > roooto:x:0:0:/rooooto:/bin/bash > > 1111111111111111111111111111111 > > Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > > \[root@localhost \~\]# sed 's@ot@to@g' /etc/grep.txt > > rto:x:0:0:/rto:/bin/bash > > operator:x:11:0:operator:/roto:/sbin/nologin > > operator:x:11:0:operator:/rooto:/sbin/nologin > > roooto:x:0:0:/rooooto:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 现在思考一下如何删除文档中的所有的数字或者字母?示例命令如下: > \[root@localhost \~\]# sed 's/\[0-9\]//g' /etc/grep.txt > > rot:x:::/rot:/bin/bash > > operator:x:::operator:/root:/sbin/nologin > > operator:x:::operator:/rooot:/sbin/nologin > > roooot:x:::/rooooot:/bin/bash > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \[0-9\]表示任意的数字。这里你也可以提携程\[a-zA-Z\]或者\[0-9a-zA-Z\]。如下所示: > \[root@localhost \~\]# sed 's/\[a-zA-Z\]//g' /etc/grep.txt > > ::0:0:/:// > > ::11:0::/:// > > ::11:0::/:// > > ::0:0:/:// > > 1111111111111111111111111111111 #### **2.2.5调换两个字符串的位置** 示例命令如下: > \[root@localhost \~\]# sed 's/\\(rot\\)\\(.\*\\)\\(bash\\)/\\3\\2\\1/' /etc/grep.txt > > bash:x:0:0:/rot:/bin/rot > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 小括号在sed中属于特殊符号,必须在前面加转义字符\\,替换时间则写成类似\\1,\\2或\\3的形式。上例中用()把想要替换的字符打包成一个整体。有这个转义字符\\,会让这个表达式看起来乱糟糟的,有个办法可以省略他。如下所示: > \[root@localhost \~\]# sed -r 's/(rot)(.\*)(bash)/\\3\\2\\1/' /etc/grep.txt > > bash:x:0:0:/rot:/bin/rot > > operator:x:11:0:operator:/root:/sbin/nologin > > operator:x:11:0:operator:/rooot:/sbin/nologin > > roooot:x:0:0:/rooooot:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 没错正如你所看到的,就是这个-r选项让这个表达式更加清晰了。除了调换两个字符串的位置,还常常用sed在某一行前后增加指定内容,如下所示: > \[root@localhost \~\]# sed 's/\^.\*$/123\&/' /etc/grep.txt > > 123rot:x:0:0:/rot:/bin/bash > > 123operator:x:11:0:operator:/root:/sbin/nologin > > 123operator:x:11:0:operator:/rooot:/sbin/nologin > > 123roooot:x:0:0:/rooooot:/bin/bash > > 1231111111111111111111111111111111 > > 123aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa #### **2.2.6直接修改文件内容** 示例命令如下: > \[root@localhost \~\]# sed -i 's/ot/to/g' /etc/grep.txt > > \[root@localhost \~\]# cat /etc/grep.txt > > rto:x:0:0:/rto:/bin/bash > > operator:x:11:0:operator:/roto:/sbin/nologin > > operator:x:11:0:operator:/rooto:/sbin/nologin > > roooto:x:0:0:/rooooto:/bin/bash > > 1111111111111111111111111111111 > > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 这样就可以直接更改grep.txt文件中的内容了。但需要注意,在修改前最好先备份文件,以免改错。 ### **2.3awk工具的使用** awk也是流式编辑器,针对文档中的行来操作,一行一行的执行。awk兼具sed的所有功能,而且更加强大。 #### **2.3.1截取文档中的某个段** 示例命令如下: > \[root@localhost \~\]# head -2 /etc/grep.txt \|awk -F ':' '{print $1}' > > rto > > operator 本例中,-F选项的作用是指定分隔符。如果不加-F选项,则以空格或者tab位分隔符。Print为打印的动作,用来打印某个字段。$1为第一个字段,$2为第二个字段,以此类推。但$0比较特殊,他表示整行: > \[root@localhost \~\]# head -2 /etc/grep.txt \|awk -F':' '{print $0}' > > rto:x:0:0:/rto:/bin/bash > > operator:x:11:0:operator:/roto:/sbin/nologin 注意awk的格式,-F后面紧跟单引号,单引号里面为分隔符,print的动作要用{}括起来,否则会报错。配套还可以打印自定义内容,但是自定义的内容必须用括号括起来。如下所示: > \[root@localhost \~\]# head -2 /etc/grep.txt \|awk -F ':' '{print $1"#"$2"#"$3}' > > rto#x#0 > > operator#x#11 #### **2.3.2匹配字符或者字符串** 示例命令如下: > \[root@localhost \~\]# awk '/oo/' /etc/grep.txt > > operator:x:11:0:operator:/rooto:/sbin/nologin > > roooto:x:0:0:/rooooto:/bin/bash 这跟sed的用法类似,能实现grep的功能,但没有展示颜色,肯定没有grep用起来方便。不过awk还有比sed更强大的匹配,如下所示: > \[root@localhost \~\]# awk -F ':' '$1 \~/oo/' /etc/grep.txt > > roooto:x:0:0:/rooooto:/bin/bash 他可以让某个段去匹配,这里\~就是匹配的意思。awk还可以多次匹配,如下所示: > \[root@localhost \~\]# awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' /etc/grep.txt > > operator 11 本例中awk匹配完root,在匹配test,他可以只打印所匹配的段。 #### **2.3.3条件操作符** 示例命令如下: > \[root@localhost \~\]# awk -F ':' '$3=="0"' /etc/passwd > > root:x:0:0:root:/root:/bin/bash Awk中可以用逻辑符号进行判断,比如==就是等于,也可以理解为精确匹配。另外还有\>,\>=,\<,\<=,!=等。值得注意的是,在和数字比较式,若把比较的数字用双引号引起来,那么awk不会认为是数字、会认为是字符,不加双引号则会认为是数字。 > \[root@localhost \~\]# awk -F ':' '$3\>=500' /etc/passwd > > polkitd:x:999:998:User for polkitd:/:/sbin/nologin > > chrony:x:998:996::/var/lib/chrony:/sbin/nologin > > \[root@localhost \~\]# awk -F ':' '$3\>="500"' /etc/passwd > > shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown > > halt:x:7:0:halt:/sbin:/sbin/halt > > mail:x:8:12:mail:/var/spool/mail:/sbin/nologin > > nobody:x:99:99:Nobody:/:/sbin/nologin > > dbus:x:81:81:System message bus:/:/sbin/nologin > > polkitd:x:999:998:User for polkitd:/:/sbin/nologin > > sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin > > postfix:x:89:89::/var/spool/postfix:/sbin/nologin > > chrony:x:998:996::/var/lib/chrony:/sbin/nologin !=表示不匹配,他除了针对某一个段的字符进行逻辑比较外,还可以在两个段之间进行逻辑比较。如下所示: > \[root@localhost \~\]# awk -F ':' '$7!="/sbin/nologin"' /etc/passwd > > root:x:0:0:root:/root:/bin/bash > > sync:x:5:0:sync:/sbin:/bin/sync > > shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown > > halt:x:7:0:halt:/sbin:/sbin/halt > > \[root@localhost \~\]# awk -F ':' '$3\<$4' /etc/passwd > > adm:x:3:4:adm:/var/adm:/sbin/nologin > > lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin > > mail:x:8:12:mail:/var/spool/mail:/sbin/nologin > > games:x:12:100:games:/usr/games:/sbin/nologin > > ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 另外还可以使用\&\&和\|\|,他们分别表示"并且"和"或者"。\&\&的用法如下: > \[root@localhost \~\]# awk -F ':' '$3\>"5" \&\& $3\<"7"' /etc/passwd > > shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown \|\|的用法如下: > \[root@localhost \~\]# awk -F ':' '$3\>1000 \|\| $7=="/bin/bash"' /etc/passwd > > root:x:0:0:root:/root:/bin/bash #### **2.3.4awk的内置变量** awk常用的变量有OFS、NF和NR,OFS和-F选项有类似的功能,也是用来定义分隔符的,但是他在输出的时候定义,NF表示用分隔符的分隔后一共有多少段,NR表示行号。 OFS的用法示例如下: > \[root@localhost \~\]# head -5 /etc/passwd \|awk -F ':' '{OFS="#"} {print $1,$3,$'4} > > root#0#0 > > bin#1#1 > > daemon#2#2 > > adm#3#4 > > lp#4#7 还有更高级的一些用法: > \[root@localhost \~\]# awk -F ':' '{OFS="#"} {if ($3\>100) {print $1,$2,$3,$4}}' /etc/passwd > > systemd-network#x#192#192 > > polkitd#x#999#998 > > chrony#x#998#996 变量NF的具体用法如下: > \[root@localhost \~\]# head -n3 /etc/passwd \| awk -F ':' '{print NF}' > > 7 > > 7 > > 7 > > \[root@localhost \~\]# head -n3 /etc/passwd \| awk -F ':' '{print $NF}' > > /bin/bash > > /sbin/nologin > > /sbin/nologin 这里NF是多少段,$NF是最后一段的值。NR的具体用法如下: > \[root@localhost \~\]# head -3 /etc/passwd \| awk -F ':' '{print NR}' > > 1 > > 2 > > 3 我们还可以使用NR作为判断条件,如下所示: > \[root@localhost \~\]# awk 'NR\>10' /etc/passwd > > games:x:12:100:games:/usr/games:/sbin/nologin > > ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin > > nobody:x:99:99:Nobody:/:/sbin/nologin > > systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin > > dbus:x:81:81:System message bus:/:/sbin/nologin > > polkitd:x:999:998:User for polkitd:/:/sbin/nologin > > sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin > > postfix:x:89:89::/var/spool/postfix:/sbin/nologin > > chrony:x:998:996::/var/lib/chrony:/sbin/nologin NR也可以配合段匹配一起是使用,如下所示: > \[root@localhost \~\]# awk -F ':' 'NR\<20 \&\& $1 \~ /root/' /etc/passwd > > root:x:0:0:root:/root:/bin/bash #### **2.3.5awk中的数学运算** awk可以更改段值,示例命令如下: > \[root@localhost \~\]# head -n 3 /etc/passwd \|awk -F ':' '$1="root"' > > root x 0 0 root /root /bin/bash > > root x 1 1 bin /bin /sbin/nologin > > root x 2 2 daemon /sbin /sbin/nologin awk也可以对各个段的值进行数学运算,示例命令如下: > \[root@localhost \~\]# head -n2 /etc/passwd > > root:x:0:0:root:/root:/bin/bash > > bin:x:1:1:bin:/bin:/sbin/nologin > > \[root@localhost \~\]# head -n2 /etc/passwd \|awk -F ':' '{$7=$3+$4;print $0}' > > root x 0 0 root /root 0 > > bin x 1 1 bin /bin 2 awk还可以计算某个段的总和,示例命令如下: \[root@localhost \~\]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd 2605 这里的END是awk特有的语法,表示所有的行都已经执行。其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法。在awk中使用if判断、for循环都可以,如下所示: > \[root@localhost \~\]# awk -F ':' '{if ($1=="root") {print $0}}' /etc/passwd > > root:x:0:0:root:/root:/bin/bash

相关推荐
___波子 Pro Max.3 小时前
正则表达式和通配符
正则表达式
北极象19 小时前
用C实现一个最简单的正则表达式引擎
c语言·正则表达式·php
学吧别真挂了20 小时前
正则表达式从入门到飞升:覆盖90%前端场景的秘籍
前端·javascript·正则表达式
bst@微胖子1 天前
正则表达式示例集合
正则表达式
星如雨落2 天前
Linux Shell 脚本使用YAD工具实现Shell图形化界面
linux·shell
苏琢玉3 天前
MySQL 备份 Shell 脚本:支持远程同步与阿里云 OSS 备份
mysql·shell
智能编织者3 天前
深入解析 Python 正则表达式:全面指南与实战示例
python·mysql·正则表达式
課代表3 天前
VBA 中正则表达式使用指南
数据库·mysql·正则表达式·excel
南隅。4 天前
【C++】基础3——正则表达式,静态多态(函数重载和模板),异常处理
开发语言·c++·正则表达式
BabyFish134 天前
notepad++ 正则表达式
正则表达式·notepad++