3.23 第十一章:正则表达式

第十一章:正则表达式

一、grep/egrep工具的使用

格式:grep 【-cinvABC】 ‘关键词’ filename。

  • -c:不是打印符合要求的行数;
  • -i:表示忽略大小写;
  • -n:表示输出符合要求的行及其行号;
  • -v:表示打印不符合要求的行;
  • -A:后面跟一个数字(有无空格都可以),例如-A2表示打印符合要求的行以及下面两行;
  • -B:后面跟一个数字,例如-B2表示打印符合要求的行以及上面两行;
  • -C:后面跟一个数字,例如-C2表示打印符合要求的行以及上下两行。

下面是对于-A2、-B2、-C2用法的演示:

[root@zl_cloud ~]# 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
[root@zl_cloud ~]# 
[root@zl_cloud ~]# 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
[root@zl_cloud ~]# 
[root@zl_cloud ~]# 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
[root@zl_cloud ~]# 

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

格式:grep -n ‘关键词’ 【文件】

[root@zl_cloud ~]# grep -n 'root' /etc/passwd   //前面数字为行号
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@zl_cloud ~]# 

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

格式:grep -nv ‘关键词’ 【文件】

[root@zl_cloud ~]# grep -nv 'nologin' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
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
22:user1:x:1000:1000::/home/user1:/bin/bash
23:usertest:x:1001:1002::/home/usertest:/bin/bash
24:usertest1:x:1003:1002:usertest1,1,1,1:/home/usertest1:/bin/bash
25:test:x:1004:1004::/home/test:/bin/bash
26:zl:x:1005:1005::/home/zl:/bin/bash
[root@zl_cloud ~]# 

3.过滤出所有包含数字的行

格式:grep ‘[数字范围]’ 【文件】

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

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

格式:grep -v ‘[数字范围]’ 【文件】

[root@zl_cloud ~]# 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
#
[root@zl_cloud ~]# 

5.过滤掉所有以#开头的行

格式:grep -v '^#'【文件】

[root@zl_cloud ~]# cat 1.txt    //源文件
TEST

aaaaaaa
#111
#222
111
222
[root@zl_cloud ~]# grep -v '^#' 1.txt    //过滤后,它是包含空行的
TEST

aaaaaaa
111
222
[root@zl_cloud ~]# 

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

格式:grep -v '^#' 【文件】 | grep -v ‘^$’

[root@zl_cloud ~]# grep -v '^#' 1.txt | grep -v '^$'
TEST
aaaaaaa
111
222
[root@zl_cloud ~]# 

如何打印出不以英文字母开头的行呢:
格式:grep '^[^a-zA-Z]'【文件】

[root@zl_cloud ~]# cat 1.txt
TEST
123
abc
456

abc222
#hjftdug
Afdhg
[root@zl_cloud ~]# grep '^[^a-zA-Z]' 1.txt     //除字母开头
123
456
#hjftdug
[root@zl_cloud ~]# grep '[^a-zA-Z]' 1.txt
123
456
abc222
#hjftdug
[root@zl_cloud ~]# 

[^字符]表示除[ ]内字符之外的字符,在正则表达式中,^表示行的开始,$表示行的结尾。

7.过滤出任意一个字符和重复字符

格式:grep '字符.字符' filename

[root@zl_cloud ~]# grep 'r.o' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@zl_cloud ~]# 

.表示任意一个字符

[root@zl_cloud ~]# 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
[root@zl_cloud ~]# 

*表示零个或多个*前面的字符。ooo*表示oo、ooo、oooo…或者更多的o

[root@zl_cloud ~]# grep '.*' /etc/passwd | wc -l
26
[root@zl_cloud ~]# 

.*表示零个或多个任意字符,空行也包含在内。

[root@zl_cloud ~]# wc -l /etc/passwd
26 /etc/passwd
[root@zl_cloud ~]# 

8.指定要过滤出的字符出现次数

格式:grep '字符\{数字\}' filename

[root@zl_cloud ~]# grep 'o\{2\}' /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
[root@zl_cloud ~]# 

这里用到了符号{ },其内部为数字,表示前面的字符要重复的次数。需要强调的是,{ }左右都需要加上转义字符。另使用{ }时还可以表示一个范围,具体格式为{n1,n2},n2还可以为空,这时表示大于等于n1次。

egrep时grep的扩展版本,可以完成grep不能完成的工作。先编辑一个这样的内容文件方便实验:

[root@zl_cloud ~]# cat test.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@zl_cloud ~]# 

9.过滤处一个或多个指定的字符

格式:grep '字符+' filename

[root@zl_cloud ~]# egrep 'o+' test.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@zl_cloud ~]# egrep 'oo+' test.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@zl_cloud ~]# egrep 'ooo+' test.txt
operator:x:11:0:operator:/rooot:/sbin/nologin
roooot:x:0:0:/rooooot:/bin/bash
[root@zl_cloud ~]# 

和grep不同,这里使用的时符号+,他表示匹配1个或多个前面的字符。{ }符号可以直接被egrep使用,而不用加\转义:

[root@zl_cloud ~]# egrep 'o{2}' /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
[root@zl_cloud ~]# 

10.过滤处零个或一个指定的字符

格式:egrep '字符?' filename

[root@zl_cloud ~]# egrep 'o?' test.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@zl_cloud ~]# egrep 'ooo?' test.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@zl_cloud ~]# egrep 'oooo?' test.txt
operator:x:11:0:operator:/rooot:/sbin/nologin
roooot:x:0:0:/rooooot:/bin/bash
[root@zl_cloud ~]# 

11.过滤处字符串1或者字符串2

格式:egrep '字符|字符|字符' filename

[root@zl_cloud ~]# egrep 'aaa|111|ooo' test.txt
operator:x:11:0:operator:/rooot:/sbin/nologin
roooot:x:0:0:/rooooot:/bin/bash
1111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@zl_cloud ~]# 

12.egrep中()的应用

格式:egrep '字符(字符|字符)字符' filename

[root@zl_cloud ~]# egrep 'r(oo|at)o' test.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@zl_cloud ~]# 

这里用()表示一个整体,上例会把包含root或者rato的行过滤出来,另外也可以()和其他字符组合在一起,例如(oo)+就表示1个或者多个oo:

[root@zl_cloud ~]# egrep '(oo)+' test.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@zl_cloud ~]# 

二、sed工具的使用

1.打印某行

格式:sed -n ‘n’p filename,单引号内的n是一个数字,表示第几行。-n选项的作用是只显示我们要打印的行,无关紧要的内容不显示。

[root@zl_cloud ~]# sed -n '2'p /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
[root@zl_cloud ~]# 

你可以去掉-n选项对比一下差异。要想把所有行都打印出来,可以使用使用命令sed -n ’1,$’p filename。(其实我去掉了-n后发现也就是把文件内容全打印出来了,跟这个内容是一样的。个人觉得cat不是更好嘛)

[root@zl_cloud ~]# sed -n '1,$'p test.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@zl_cloud ~]# 
[root@zl_cloud ~]# sed -n '1,3'p test.txt
rot:x:0:0:/rot:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
operator:x:11:0:operator:/rooot:/sbin/nologin
[root@zl_cloud ~]# 

2.打印包含某个字符串的行

格式:sed -n ‘/字符串/’p filename

[root@zl_cloud ~]# sed -n '/root/'p test.txt
operator:x:11:0:operator:/root:/sbin/nologin
[root@zl_cloud ~]# 

这种用法就类似于grep了,在grep中使用的特殊字符(如^$.*等)同样也能在sed中使用:

[root@zl_cloud ~]# sed -n '/^1/'p test.txt
1111111111111111111111111111111
[root@zl_cloud ~]# sed -n '/in$/'p test.txt
operator:x:11:0:operator:/root:/sbin/nologin
operator:x:11:0:operator:/rooot:/sbin/nologin
[root@zl_cloud ~]# sed -n '/r..o/'p test.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@zl_cloud ~]# sed -n '/ooo*/'p test.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@zl_cloud ~]# 

sed命令加上-e选项可以实现多个行为

[root@zl_cloud ~]# sed -e '1'p -e '/111/'p -n test.txt
rot:x:0:0:/rot:/bin/bash
1111111111111111111111111111111
[root@zl_cloud ~]# 

3.删除某些行

删除指定单行:
格式:sed ‘n’d filename

[root@zl_cloud ~]# sed '1'd test.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

删除指定多行:
格式:sed ‘n1,n2’p filename

[root@zl_cloud ~]# sed '1,3'd test.txt
roooot:x:0:0:/rooooot:/bin/bash
1111111111111111111111111111111
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

删除匹配某个字符的行:
格式:sed ‘/字符串/’d filename

[root@zl_cloud ~]# sed '/oot/'d test.txt
rot:x:0:0:/rot:/bin/bash
1111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@zl_cloud ~]# 

这些操作仅仅是在显示器屏幕上不显示这些行而已,并不是真的删除文档。

4.替换字符或者字符串

格式:sed ‘n1,n2s/字符串/字符串/g’ filename

[root@zl_cloud ~]# sed '1,2s/ot/to/g' test.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
[root@zl_cloud ~]# 

参数s代表替换动作,参数g表示本行全局替换,如果不加g则只替换本行出现的第一个,跟vi的替换差不多。
除了可以使用/作为分隔符外,还可以使用其他特殊字符,例如#和@:

[root@zl_cloud ~]# sed 's#ot#to#g' test.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@zl_cloud ~]# sed 's@ot@to@g' test.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@zl_cloud ~]# 

如何让删除文档中所有的数字或者字母?命令如下:
格式:sed ‘s/[n1-n2]//g’ filename(这里是替换为空)

[root@zl_cloud ~]# sed 's/[0-9]//g' test.txt
rot:x:::/rot:/bin/bash
operator:x:::operator:/root:/sbin/nologin
operator:x:::operator:/rooot:/sbin/nologin
roooot:x:::/rooooot:/bin/bash

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@zl_cloud ~]# 

[0-9]表示任意的数字。也可以写成[a-zA-Z]或者[0-9a-zA-Z]:
格式:sed ‘s/[a-zA-Z]//g’ filename(这里是替换为空)

[root@zl_cloud ~]# sed 's/[a-zA-Z]//g' test.txt
::0:0:/://
::11:0::/://
::11:0::/://
::0:0:/://
1111111111111111111111111111111

[root@zl_cloud ~]# 

5.调换两个字符串的位置

格式:sed 's/\(字符串\)\(.*\)\(字符串\)/\3\2\1/’ filename

[root@zl_cloud ~]# sed 's/\(rot\)\(.*\)\(bash\)/\3\2\1/' test.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
[root@zl_cloud ~]# 

小括号在sed中属于特殊符号,必须在前面加转义字符\,替换时则携程类似\、\2或\3的形式。括号只是想把替换的字符打包成一个整体。如何省略转义字符呢?加-r选项!
格式:sed -r 's/(字符串)(.*)(字符串)/\3\2\1/’ filename

[root@zl_cloud ~]# sed -r 's/(rot)(.*)(bash)/\3\2\1/' test.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
[root@zl_cloud ~]# 

除了调换两个字符串的位置,有时候常常会用sed在某一行前后增加指定内容
格式:sed 's/^.*$/指定内容$/’ filename

[root@zl_cloud ~]# sed 's/^.*$/123&/' test.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
[root@zl_cloud ~]# 

6.直接修改文件的内容

格式:sed -i 's/(字符串)/(字符串)/g’ filename

[root@zl_cloud ~]# sed -i 's/ot/to/g' test.txt
[root@zl_cloud ~]# cat test.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@zl_cloud ~]# 

三、awk工具的使用

1.截取文档中的某个段

  • -F:指定分隔符;(不加以空格或者tab为分隔符)
    格式:awk -F ':' '{print 字段}'
[root@zl_cloud ~]# head -n2 test.txt | awk -F ':' '{print $1}'    $1为第一个字段
rto
operator
[root@zl_cloud ~]# 
[root@zl_cloud ~]# head -n2 test.txt | awk -F ':' '{print $0}'    $0比较特殊,表示整行
rto:x:0:0:/rto:/bin/bash
operator:x:11:0:operator:/roto:/sbin/nologin
[root@zl_cloud ~]# 

注意awk的格式,-F后面紧跟单引号,单引号里面为分隔符。print的动作要用{ }括起来,否则会报错。print还可以打印自定义内容,但是自定义内容要用双括号括起来:
格式:awk -F ':' '{print 字段 “自定义内容”}'

[root@zl_cloud ~]# head -n2 test.txt | awk -F ':' '{print $1"#""$2""#""$3""#""$4"}'
rto#$2#$3#$4
operator#$2#$3#$4
[root@zl_cloud ~]# 

2.匹配字符或者字符串

格式:awk ‘/字符/’ filename

[root@zl_cloud ~]# awk '/oo/' test.txt
operator:x:11:0:operator:/rooto:/sbin/nologin
roooto:x:0:0:/rooooto:/bin/bash
root:x:0:0:root:/root:/bin/bash 
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/vai/spool/inail:/sbin/nologin 
operator:x:il:0:operator:/root:/sbin/nologin 
Postfix:x:89:89::/var/spool/po$tfix:/sbin/nologin 
setroubleshoot:x:992:990::/var/lib/setioubleshoot:/sbin/nologin
[root@zl_cloud ~]# 

跟sed用法相似,能实现grep的功能。不过awk还有比sed更强大的匹配:
格式:awk -F ‘:’ ‘字段~/字符/’ filename

[root@zl_cloud ~]# awk -F ':' '$1~/oo/' test.txt
roooto:x:0:0:/rooooto:/bin/bash
root:x:0:0:root:/root:/bin/bash 
setroubleshoot:x:992:990::/var/lib/setioubleshoot:/sbin/nologin
[root@zl_cloud ~]# 

它可以让某个字段去匹配,~就是匹配的意思,并且awk可以多次匹配:

[root@zl_cloud ~]# awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' test.txt
operator 11
root 0
operator il
[root@zl_cloud ~]# 

本例中awk匹配完root,再匹配test,还可以打印所匹配的段。

3.条件操作符

格式:awk -F ‘:’ ‘字段==“值”’ filename

[root@zl_cloud ~]# awk -F ':' '$3=="0"' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@zl_cloud ~]# 

可以用逻辑符号进行判断,比如==就是等于,也可以理解为精确匹配。另外还有>、>=、<、<=、!=等。值得注意的是在和数字比较时,若是把比较的数字用双引号引起来,那么awk不会认为是数字,而是认为是字符,不加双引号则会认为是数字。
格式:awk -F ‘:’ ‘字段>=“值”’ filename

[root@zl_cloud ~]# 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
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@zl_cloud ~]# 

不加双引号后:(这个原理跟sort排序一样。)
格式:awk -F ‘:’ ‘字段>=值’ filename

[root@zl_cloud ~]# awk -F ':' '$3>=500' /etc/passwd
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
user1:x:1000:1000::/home/user1:/bin/bash
usertest:x:1001:1002::/home/usertest:/bin/bash
usertest1:x:1003:1002:usertest1,1,1,1:/home/usertest1:/bin/bash
test:x:1004:1004::/home/test:/bin/bash
zl:x:1005:1005::/home/zl:/bin/bash
[root@zl_cloud ~]# 
[root@zl_cloud ~]# 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
user1:x:1000:1000::/home/user1:/bin/bash
usertest:x:1001:1002::/home/usertest:/bin/bash
usertest1:x:1003:1002:usertest1,1,1,1:/home/usertest1:/bin/bash
test:x:1004:1004::/home/test:/bin/bash
zl:x:1005:1005::/home/zl:/bin/bash
[root@zl_cloud ~]# 

本例中,!=表示不匹配,他除了针对某一个段的字符进行逻辑比较外,还可以在两个段之间进行逻辑比较。
格式:awk -F ‘:’ ‘字段 比较符号 字段’ filename

[root@zl_cloud ~]# 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
usertest:x:1001:1002::/home/usertest:/bin/bash
[root@zl_cloud ~]# 

另外还可以使用&&和||,分别表示并且和或者:

[root@zl_cloud ~]# awk -F ':' '$3>"5" && $3<"7"' /etc/passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
[root@zl_cloud ~]# awk -F ':' '$3>1000 || $7=="/bin/bash"' /etc/passwd
root:x:0:0:root:/root:/bin/bash
user1:x:1000:1000::/home/user1:/bin/bash
usertest:x:1001:1002::/home/usertest:/bin/bash
usertest1:x:1003:1002:usertest1,1,1,1:/home/usertest1:/bin/bash
test:x:1004:1004::/home/test:/bin/bash
zl:x:1005:1005::/home/zl:/bin/bash
[root@zl_cloud ~]# 

4.awk的内置变量

awk常用的变量有OFS、NF和NR,OFS和-F选项有类似的功能,也是用来定义分隔符的,但是他是在输出的时候定义,NF表示用分隔符分隔后一共有多少段,NR表示行号。
①OFS(NR,OFS和-F选项有类似的功能,也是用来定义分隔符的,但是他是在输出的时候定义

[root@zl_cloud ~]# 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@zl_cloud ~]# 
[root@zl_cloud ~]# awk -F ':' '{OFS="#"} {if($3>1000) {print $1,$2,$3,$4}}' /etc/passwd
usertest#x#1001#1002
usertest1#x#1003#1002
test#x#1004#1004
zl#x#1005#1005
[root@zl_cloud ~]# 

②NF(NF表示用分隔符分隔后一共有多少段。NF是多少段,$NF是最后一段的值)

[root@zl_cloud ~]# head -n3 /etc/passwd |awk -F ':' '{print NF}'
7
7
7
[root@zl_cloud ~]# head -n3 /etc/passwd |awk -F ':' '{print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
[root@zl_cloud ~]# 

③NR(NR表示行号。可做判断条件,也可以配合段匹配一起使用)

[root@zl_cloud ~]# head -n3 /etc/passwd |awk -F ':' '{print NR}'
1
2
3
[root@zl_cloud ~]#
[root@zl_cloud ~]# awk 'NR>40' /etc/passwd
...
[root@zl_cloud ~]#
[root@zl_cloud ~]# awk -F ':' 'NR<20 && $1 ~ /roo/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@zl_cloud ~]# 

5.awk中的数学运算

awk可以更改段值:

[root@zl_cloud ~]# 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
[root@zl_cloud ~]# 

对各个段的值进行数学运算:

[root@zl_cloud ~]# head -n2 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@zl_cloud ~]# 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 
[root@zl_cloud ~]#

计算某个段的总和:

[root@zl_cloud ~]# awk -F ':' '{(tot=tot+$3)};END {print tot}' /etc/passwd
8652
[root@zl_cloud ~]# 

这里的END是awk特有的语法,表示所有的行都已经执行。
其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法。在awk中使用if判断,for循环都可以:

[root@zl_cloud ~]# awk -F ':' '{if ($1=="root") {print $0}}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@zl_cloud ~]# 

猜你喜欢

转载自blog.csdn.net/zhang_ZERO/article/details/105061112