设为首页 收藏本站
查看: 938|回复: 0

[经验分享] linux正则表达式

[复制链接]
累计签到:67 天
连续签到:1 天
发表于 2018-10-23 13:15:18 | 显示全部楼层 |阅读模式
linux正则表达式grep和egrep
正则表达式:它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索或替换那些符合某个模式的文本内容。
其实正则表达式,只是一种思想,一种表示方法。只要我们使用的工具支持表示这种思想那么这个工具就可以处理正则表达式的字符串。常用的工具有grep,sed, awk,这三个都是针对文本的行才操作的。
grep   过滤器
语法: grep [-cinvABC]  'word'  filename
-n    显示行号
-c    count统计符合要求的行数
-v    取反,不包含所选字符的
-i    不区分大小写
-r    会把目录下面所有的文件遍历  例如: grep -r 'root' ./
-A    后面跟数字,A2表示打印符合要求的行及下面二行
-B    后面跟数字,B2表示打印符合要求的行及上面二行
-C    后面跟数字,C2表示打印符合要求的行及上下各二行
^     行首,开头
$     行尾,结尾
空行用 ^$ 表示         
可以做一个别名alias grep="grep --color" 写入到.bashrc里面;以后输入grep命令时查找的关键字符会颜色显示,方便区分。
过滤带有某个关键词的行并输出行号,颜色显示关键词
[root@localhost~]# grep -n --color 'root' passwd
1:root:x:0:0:root:/root:/bin/bash
11:operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost~]# grep -o --color 'root' passwd | wc -l
4
加-o 统计包含关键词的个数;
过滤不带有某个关键词的行,并输出行号;
[root@yonglinux~]# 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
20:user1:x:600:501::/home/user1:/bin/bash
23:mysql:x:27:27:MySQLServer:/var/lib/mysql:/bin/bash
过滤以nologin结尾的,系统禁止登陆的所有用户;
[root@localhost~]# grep 'nologin$' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
示例,打印关键字halt所在行的A2 B2 C2
[root@yonglinux~]# grep -A2 'halt' passwd
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[root@yonglinux~]# grep -B2 'halt' 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@yonglinux~]# grep -C2 'halt' 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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
把所有以#号开头的行去除
[root@yonglinux~]# grep -v '^#' /etc/inittab
id:3:initdefault:
去除所有空行和以#号开头的行
[root@yonglinux~]# grep -v '^#' /etc/crontab |grep -v '^$'
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
示例说明,打印数字或字母开头,及不是字母和数字开头的;
[root@yonglinuxtmp]# cat test.txt
helloworld
abc
abc11111
#differt
12345
67899
123def
[0-9]代表任意一个数字,整个命令意思筛选出包含任意一个数字的行;
[root@yonglinuxtmp]# grep '[0-9]' test.txt
abc11111
12345
67899
123def
[^0-9]代表除0-9之外的任意一个字符,整个命令的意思是筛选出不包含数字的行,只要这一行中含有非数字即可,(即不全是数字)
[root@yonglinuxtmp]# grep '[^0-9]' test.txt
helloworld
abc
abc11111
#differt
123def
^[^0-9]代表不是数字开头的;
[root@yonglinuxtmp]# grep '^[^0-9]' test.txt
helloworld
abc
abc11111
#differt
[a-z]代表任意一个英文字母;
[root@yonglinuxtmp]# grep '[a-z]' test.txt
helloworld
abc
abc11111
#differt
123def
[^a-z]代表除英文字母以外的;
[root@yonglinuxtmp]# grep '[^a-z]' test.txt
abc11111
#differt
12345
67899
123def
^[^a-z]代表不是英文字母开头的文本;
[root@yonglinuxtmp]# grep '^[^a-z]' test.txt
#differt
12345
67899
123def
[ ] 如果是数字的话就用[0-9]这样的形式,当然有时候也可以用这样的形式[15]即只含有1或者5,注意,它不会认为是15。如果要过滤出数字以及大小写字母则要这样写[0-9a-zA-Z]。另外[]还有一种形式,就是[^字符] 表示除[ ]内的字符之外的字符。
过滤任意一个字符与重复字符
[root@yonglinux~]# grep 'h..t' /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt
'.'点表示任意的一个字符,上面例子为把符合h与t之间有2个任意字符的行过滤出来。
'*'代表零个或多个任意的字符
'ooo*'代表oo,ooo,oooo 或者更多的o
[root@yonglinux~]# 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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
'.*'表示零个或多个任意字符,等于所有的,空行也包含在内。
[root@yonglinux~]# grep '.*' /etc/passwd |wc -l
24
[root@yonglinux~]# wc -l /etc/passwd
24 /etc/passwd
指定要过滤字符出现的次数
{ }内部为数字,表示前面字符要重复的次数。表示两个O即包含OO的行。{ }左右都需要加脱意字符\
grep -E 代表增强版的grep即egrep,使用egrep不需要脱意;
[root@yonglinux~]# 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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
[root@localhost~]# grep -E 'o{2}'passwd
[root@localhost~]# egrep 'o{2}' passwd
[root@yonglinux~]# cat test.txt
root:hot
abcde
spoool
spool
spol
spl
示例,过滤字母o出现1到3次的行
[root@yonglinux~]# grep 'o\{1,3\}' test.txt
root:hot
spoool
spool
spol
{ } 还可以表示一个范围,格式为{n1,n2} n1<n2表示重复n1到n2次前面的字符,n2还可以为空,则表示大于等于n1次。
egrep为grep的扩展版本,我们可以用egrep完成grep不能完成的工作,当然了grep能完成的egrep完全可以完成。
grep -E = egrep
1、筛选一个或一个以上前面的字符    字符后面使用+
[root@yonglinux~]# cat test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# egrep 'o+' test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
[root@yonglinux~]# egrep 'oo+' test.txt
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
[root@yonglinux~]# egrep 'ooo+' test.txt
rooooot:x:0:0/roooooot:/bin/bash
2、筛选零个或一个前面的字符   字符后面使用?
[root@yonglinux~]# egrep 'o?' test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# egrep 'oo?' test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
[root@yonglinux~]# egrep 'ooo?' test.txt
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
[root@yonglinux~]# egrep 'oooo?' test.txt
rooooot:x:0:0/roooooot:/bin/bash
3、筛选字符串1或字符串2  包含里面任意一个字符串的打印出来
[root@yonglinux~]# egrep 'aaa|111|ooo' test.txt
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
4、egrep中()的应用
[root@yonglinux~]# egrep 'r(oo)|(mo)n' test.txt
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
用( )表示一个整体,例如(oo)+ 表示1个'oo'或者多个'oo'
[root@yonglinux~]# egrep '(oo)+' test.txt
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
5、egrep中[ ]的应用   
方括号内的字符为其中的一个;[^o]为除了字母o之外的;
示例:r开头t结尾的;;
[root@localhost~]# egrep 'r[o]t' test.txt
rot:x:0:0:rot:/rot:/bin/bash
r开头后面有o的
[root@localhost~]# egrep 'r[o]' test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
r开头后面不是o的;
[root@localhost~]# egrep 'r[^o]' test.txt
rrt
rtx
t为结尾的前面字符不是o的;
[root@localhost~]# egrep '[^o]t' test.txt
rrt
rtx
. * + ? 符号的总结
.    表示任意一个字符(包括特殊字符 空格 # $ ?)
*    表示零个或多个*前面的字符
.*   表示任意个任意字符(包含空行)
+    表示1个或多个+前面的字符
?    表示0个或1个?前面的字符
其中,+ ? grep不支持,egrep才支持。
"ro.*t" 表示以ro开头一直到t结尾的
[root@localhost~]# grep 'ro.*t' test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
}$%KIA$XHYH{PNMDI}W(O)7.png
grep如果需要筛选字符串| 管道需要加脱意\才可以使用
H_0ZF5~4U4~{~~$EPK`Z))I.png

linux 正则表达式sed
sed、awk工具可以实现文本替换并且把替换的文本输出到屏幕上
sed和awk都是流式编辑器,是针对文档的行来操作的。sed通常用来替换操作。
示例的文本内容,以下操作根据此文本。
[root@yonglinux ~]# cat test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1、打印某一行
sed -n 'n'p filename 单引号内的n是一个数字表示第几行;p也可以写到引号内
示例打印passwd3-5
[root@yonglinux ~]# sed -n '3,5'p /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
打印所有行
[root@yonglinux ~]# sed -n '1,$'p /etc/passwd
打印某一行,并且要显示行号,需要和grep一起使用;
[root@localhost ~]# grep -n '.*' test.txt | sed -n '1'p
1:rrt
2、打印包含某个字符串的行
字符串需要用//括起来;grep中的特殊符号^ $ . * 同样适用于sed中。
[root@yonglinux ~]# sed -n '/root/'p /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
打印包含/sbin/nologin的行,/需要进行脱意
[root@yonglinux ~]# sed -n '/\/sbin\/nologin/'p passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
打印以d开头的行;打印以in结尾的;打印r与o字母中间有2个任意字符的;打印包含2个o及多个o的行;
[root@yonglinux ~]# sed -n '/^d/'p test.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@yonglinux ~]# sed -n '/in$/'p test.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@yonglinux ~]# sed -n '/r..o/'p test.txt
rooooot:x:0:0/roooooot:/bin/bash
[root@yonglinux ~]# sed -n '/ooo*/'p test.txt
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
3、-e可以实现多个行为
[root@yonglinux~]# sed -e '1'p -e '/111/'p -n test.txt
rot:x:0:0:rot:/rot:/bin/bash
11111111111111111111111111111111
可以用-e写多个;-e相当于传送带,先匹配最前面的打印,再匹配后面的打印,所以第一行会打印2次;
[root@localhost~]# sed -e '/root/p' -e '/bash/p' -n 1.txt
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
user1:x:500:500::/home/user1:/bin/bash
user2:x:501:501::/home/user2:/bin/bash
-e后面也可以用;分号;-n不能写到-e的后面,可以写在-e的前面或最后面;
[root@localhost~]# sed -e '/root/p;/bash/p' -n 1.txt
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
user1:x:500:500::/home/user1:/bin/bash
user2:x:501:501::/home/user2:/bin/bash
4、删除某行或者多行
‘d’ 这个字符就是删除的动作了,不仅可以删除指定的单行以及多行,而且还可以删除匹配某个字符的行,另外还可以删除从某一行一直到文档末行。
示例,删除第一行;删除1-3行;删除包含root关键词的行;删除第3行到最后一行所有行;
[root@yonglinux~]# sed '1'd test.txt
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# sed '1,3'd test.txt
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# sed '/root/'d test.txt
rot:x:0:0:rot:/rot:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# sed '3,$'d test.txt
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
5、替换字符或替换字符串
示例,替换第一行字母r为R;替换1-2行中ot为to;替换所有行中ot为to;
[root@localhost~]# sed '1s/r/R/g' test.txt
RRt
[root@yonglinux~]# sed '1,2s/ot/to/g' test.txt
rto:x:0:0:rto:/rto:/bin/bash
roto:x:0:0:roto:/roto:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@yonglinux~]# sed 's#ot#to#g' test.txt
rto:x:0:0:rto:/rto:/bin/bash
roto:x:0:0:roto:/roto:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooto:x:0:0/roooooto:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
与vim编辑器里面替换一样的命令格式,s代表替换,g代表全局,不加g的话只替换行的第一个;可以使用# @作为分隔符。
1s代表只替换第一行;1,3s代表第一行到第三行;不加行数的话默认为全部行。
示例,删除文档中所有的数字's/[0-9]//g'  如删除文档中所有的字母's/[a-zA-Z]//g'删除所有的数字和字母's/[0-9a-zA-Z]//g'
[root@yonglinux~]# sed 's/[0-9]//g' test.txt
rot:x:::rot:/rot:/bin/bash
root:x:::root:/root:/bin/bash
daemon:x:::daemon:/sbin:/sbin/nologin
rooooot:x::/roooooot:/bin/bash
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
示例,删除文档中所有的字母
[root@yonglinux~]# sed 's/[a-z]//g' 1.txt
::0:0:/://
::11:0::/://
::11:0::/://
::0:0:/://
1111111111111111111111111111111
示例,删除文档中不是英文字母的(数字和特殊符号)
[root@yonglinux~]# sed 's/[^a-z]//g' 1.txt
rotxrotbinbash
operatorxoperatorrootsbinnologin
operatorxoperatorroootsbinnologin
rooootxroooootbinbash
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
示例,删除文档中不是数字的(英文字母和特殊符号)
[root@yonglinux~]# sed 's/[^0-9]//g' 1.txt
00
110
110
00
1111111111111111111111111111111
示例,把文档中的小写字母全部替换为大写字母's/[a-z]/\u&/g'
[root@yonglinux~]# sed 's/[a-z]/\u&/g' 1.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
示例,把文档中的大写字母全部替换为小写字母's/[A-Z]/\l&/g'
[root@yonglinux~]# sed 's/[A-Z]/\l&/g' 1.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
替换的同时加-n p 打印特定的行;
[root@yonglinux~]# sed -n '1s/[a-z]/\u&/g'p 1.txt
ROT:X:0:0:/ROT:/BIN/BASH
6、调换二个字符串的位置
sed-r 's/([^:]+)(:.*:)([^:]+$)/\3\2\1/'
[^:]非冒号,不是冒号的所有字符
-r,--regexp-extended  在脚本中使用扩展正则表达式; 加r选项的意思为后面不用再加脱意\
( )括号括起来是分段的意思,
\3\2\1    是代表3调换1,后面的内容调换到前面
示例,aa与ff调换;加-r选项不用加脱意符号\;不加-r ( )括号左右都需要加\脱意;调换多行用最后一个;
[root@localhost~]# cat 1.txt
aa:bb:cc:dd:ee:ff
[root@localhost~]# sed -r 's/(aa)(.*)(ff)/\3\2\1/' 1.txt
ff:bb:cc:dd:ee:aa
[root@localhost~]# sed 's/\(aa\)\(.*\)\(ff\)/\3\2\1/' 1.txt
ff:bb:cc:dd:ee:aa
[root@localhost~]# sed -r 's/([^:]+)(:.*:)([^:]+$)/\3\2\1/' 1.txt
ff:bb:cc:dd:ee:aa
示例,rot与/bin/bash进行调换
[root@localhost~]# grep 'rot' test.txt
rot:x:0:0:rot:/rot:/bin/bash
[root@localhost~]# grep 'rot' test.txt |sed 's/\(rot\)\(.*\)\(\/bin\/bash\)/\3\2\1/'
/bin/bash:x:0:0:rot:/rot:rot
[root@localhost~]# grep 'rot' test.txt |sed -r 's/(rot)(.*)(/bin/bash)/\3\2\1/'
sed:-e 表达式 #1,字符 18:“s”的未知选项
[root@localhost~]# grep 'rot' test.txt |sed -r 's/(rot)(.*)(\/bin\/bash)/\3\2\1/'
/bin/bash:x:0:0:rot:/rot:rot
加-r  后()内的/bin/bash 也还需要脱意才可以;
-i 选项    直接替换字符,并且保存原文件里面。使用i选项前,记得备份原文件。
[root@localhost~]# sed -r -i 's/([^:]+)(:.*:)([^:]+$)/\3\2\1/' 1.txt
[root@localhost~]# cat 1.txt
ff:bb:cc:dd:e
linux正则表达式awk
awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk常用来分段;
awk不用加任何参数就可以实现 + ? * .  | 这些特殊符号;
1、截取文档中的某个段
[root@yonglinux~]# head -n2 passwd |awk -F: '{print $1}'
root
bin
[root@yonglinux~]# head -n2 passwd |awk -F: '{print $0}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@yonglinux~]# head -n2 passwd |awk -F: '{print $1,$3,$7}'
root 0/bin/bash
bin 1/sbin/nologin
-F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。 Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。
{ }内可以打印多个字段$1,$3,$7 打印第1、3、7段,中间用逗号隔开;
打印分段默认分隔符为空格,可以自定义分隔符,分隔符需要用双引号括起来;也可以OFS定义输出分隔符;
[root@localhost~]# awk -F: '{print $3,$4}' 1.txt |head -5
0 0
1 1
2 2
3 4
4 7
[root@localhost~]# awk -F: '{print $3":"$4}' 1.txt |head -5
0:0
1:1
2:2
3:4
4:7
[root@localhost~]# awk -F: 'OFS="#"{print $3,$4}' 1.txt |head -5
0#0
1#1
2#2
3#4
4#7
[root@yonglinux~]# head -n2 passwd |awk -F: '{print$1"#""@"$3"#"$7}'
root#@0#/bin/bash
bin#@1#/sbin/nologin
注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用 { } 括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用“”双引号括起来。
2、匹配字符或字符串
[root@yonglinux~]# awk -F: '$1~/me/' passwd
games:x:12:100:games:/usr/games:/sbin/nologin
[root@yonglinux~]# awk -F: '$1~/user/' passwd
user1:x:600:501::/home/user1:/bin/bash
可以让某个段去匹配,~ 表示匹配的意思,以冒号分隔第一字段然后匹配//里的关键字;
[root@yonglinux~]# awk -F: '/root/ {print $1,$3} /user/ {print $1,$3}' passwd
root 0
operator 11
ftp 14
saslauth 499
user1 600
awk还可以多次匹配,如上例全文匹配包含root关键词的行,再匹配包含user的行,打印所匹配的第1、3段。
3、条件操作符
判断第3个字段为0的
[root@yonglinux~]# awk -F: '$3=="0"' passwd
root:x:0:0:root:/root:/bin/bash
[root@yonglinux~]# awk -F: '$3==10' passwd
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
判断第3个字段为10的并且打印该行的第7字段;
[root@yonglinux~]# awk -F: '$3==10 {print $7}' passwd
/sbin/nologin
[root@yonglinux~]# awk -F: '$3=="600"' passwd
user1:x:600:501::/home/user1:/bin/bash
awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。
示例,双引号括起来认为是字符;加单引号和不加则认为是数字;
[root@yonglinux~]# awk -F: '$3>"500"' passwd | sort -t: -k 3 -n
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
vcsa:x:69:69:virtualconsole memory owner:/dev:/sbin/nologin
sshd:x:74:74:privilege-separatedssh:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:systemmessage bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:nobody:/:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash
[root@yonglinux~]# awk -F: '$3>500' passwd | sort -t: -k 3 -n
user1:x:600:501::/home/user1:/bin/bash
[root@yonglinux~]# awk -F: '$3>'500'' passwd | sort -t: -k 3 -n
user1:x:600:501::/home/user1:/bin/bash
!= 为不匹配,第7字段不等于/sbin/nologin的行,需要用双引号括起来。
[root@yonglinux~]# awk -F: '$7!="/sbin/nologin"' 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:600:501::/home/user1:/bin/bash
mysql:x:27:27:MySQLServer:/var/lib/mysql:/bin/bash
除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较。
示例,加双引号之后把数字当字符看;
[root@yonglinux~]# awk -F: '$3>"5" && $3<"7"' passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
vcsa:x:69:69:virtualconsole memory owner:/dev:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash
示例,加单引号之后为数字比较;
[root@yong ~]#awk -F: '$3>'5' && $3<'7' {print }' passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
另外还可以使用 && “并且”和  || “或者” 的意思。
示例,打印第3段大于第4段,并且第7段为/bin/bash的行;
[root@yonglinux~]# awk -F: '$3>$4 && $7=="/bin/bash"' passwd
user1:x:600:501::/home/user1:/bin/bash
示例,打印第3段小于第4段,或者第7段为/bin/bash的行;
[root@yonglinux~]# awk -F: '$3<$4 || $7=="/bin/bash"' passwd
root:x:0:0:root:/root:/bin/bash
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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:ftpuser:/var/ftp:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash
mysql:x:27:27:mysqlserver:/var/lib/mysql:/bin/bash
4、awk的内置变量
awk常用的变量有:
NF :用分隔符分隔后一共有多少段
NR :行数
{print NR":"NF}    列出行号,以冒号分隔,列出共有多少段;
[root@yonglinux ~]# head -5 passwd |awk -F: '{print NR":"NF}'
1:7
2:7
3:7
4:7
5:7
[root@yonglinux~]# head -5 passwd |awk -F: '{print NF}'
7
7
7
7
7
[root@yonglinux~]# head -5 passwd |awk -F: '{print NR}'
[root@yonglinux~]# head -5 passwd |awk -F: '{print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
NF 表示是多少段,而$NF是最后一段的值, 而NR则是行号。
5、awk中的数学运算
awk还可以对各个段的值进行数学运算:
[root@yonglinux~]# awk -F: '{(tot=tot+$3)};END {print tot};' passwd
1720
这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的。
示例,if判断,如第一段的值为root,打印整行;
[root@yonglinux~]# awk -F: '{if ($1=="root") print $0}' passwd
root:x:0:0:root:/root:/bin/bash
示例,for循环,定义sum变量,i值为第3段的值;求第3段的和;
[root@yonglinux~]# sum=0;for i in `awk -F: '{print $3}' passwd`;dosum=$[($sum+$i)];done;echo $sum
1720

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-625509-1-1.html 上篇帖子: linux利用密钥远程登陆 下篇帖子: linux系统日常管理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表