Shell脚本----三剑客命令(grepsedawk)
Posted handsomeboy-东
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell脚本----三剑客命令(grepsedawk)相关的知识,希望对你有一定的参考价值。
正则表达式
理解三剑客命令前得理解正则表达式,正则表达式是运用三剑客命令的基本语法
基础正则表达式元字符
- \\ :转义字符,用于取消特殊符号的含义,如:\\!、\\$
- ^ :匹配字符串开始的位置,如:^root 匹配以root开头的行,
- $ :匹配字符串结束的位置,如:world$匹配以world结尾的行
- . :匹配除\\n外的任意一个字符
- * :匹配前面的子表达式0次或者多次
- [ ] : 匹配[ ]中的一个字符,如:[0-9]匹配任意一个数字
- [^] :匹配不在[ ]中的任意一个字符,如:[^0-9]匹配任意一个非数字字符
- \\{n\\} :匹配前面子表达式n次,如:[0-9]\\{2\\}匹配两位数字
- \\{n,m\\} :匹配前面的子表达式n到m次,如:[a-z]\\{2,3\\}表示匹配两到三位小写字母
- \\{n,\\} :匹配前面的子表达式不少于n次,如:[0-9]\\{2,\\}表示两位及两位以上数字
- \\< : 匹配以……开头的行
- \\> : 匹配以……结尾的行
- \\<……\\> : 匹配某一个单词的行
拓展元字符
- + ;匹配前一个字符1个或多个,如:go+d,将匹配至少一个o
- ? :匹配0个或1个字符,如:go?d,将匹配到gd或god
- | :或
- () : 将括号中的字符串作为一个整体
- {n} : 前一个字符重复n次
- {n,} : 前一个字符至少重复n次
- {n,m} : 前一个字符出现n-m次
grep
grep命令使用选项规则
grep -v “text” :过滤掉包含text的内容查看剩下的文件内容
grep “text” :查看文件中包含text的行
grep “^q” :查看文件中以q开头的内容
grep “g$” :查看以g结尾的文件内容
grep “q*” :这里*代表前面一个字母出现0次或多次
grep -v “^$” :过滤掉文件里的空行
grep “[rR]oot” :[]里表示R或r的字母,相当于查找包含root或Root的文件内容
grep -E “^root|Root$” 文件 :-E代表引入正则,这里的|代表或的意思,这条命令表示查找以root开头Root结尾的文件内容
grep -E也可以直接写egrep
grep -c :显示有几行
grep -w “text” :只找text这个单词的文件内容
grep -i :忽略大小写查看文件内容
grep -o “text” :只以行显示text这个字符
[root@localhost ww]# grep root /etc/passwd //匹配文件中包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ww]# grep ^root /etc/passwd //匹配文件中以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@localhost ww]# grep bash$ /etc/passwd //匹配文件中以bash结尾的行
root:x:0:0:root:/root:/bin/bash
whd:x:1000:1000:whd:/home/whd:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
[root@localhost ww]# grep 'r..d' /etc/passwd //匹配r和d之间有两个任意字符的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost ww]# grep '[^s]bin' /etc/passwd //匹配bin前面不是s的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
whd:x:1000:1000:whd:/home/whd:/bin/bash
[root@localhost ww]# grep '4\\{1,\\}' /etc/passwd //匹配数字4出现1次及以上的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
unbound:x:994:989:Unbound DNS resolver:/etc/unbound:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
setroubleshoot:x:990:984::/var/lib/setroubleshoot:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
username3:x:1004:1004::/home/username3:/bin/bash
username4:x:1005:1005::/home/username4:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
[root@localhost ww]# grep -e "ntp" -e "root" /etc/passwd //-e参数匹配多个条件
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
[root@localhost ww]# grep '^[a-z]ae' /etc/passwd //匹配ae前面是小写字母开头的行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ww]# grep '[^a-z]ae' /etc/passwd //匹配ae前面不是小写字母的行
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sed
Sed是文本处理工具,依赖于正则表达式,重要用于苏交互式替换修改文件,可以对文本内容进行增删改查,sed在处理数据时默认不修改文件内容,而是把当前处理的行存储在临时缓冲区中,所有指令都在缓冲区中操作,处理完成后把缓冲区内容默认输出到屏幕
set -e ‘编辑命令’ 文件名 :指定要执行的命令,
set -n ‘编辑命令’ 文件名 :只输出处理后的行,读入时不显示
set -i ‘编辑命令’ 文件名 :直接编辑文件,而不输出结果
set -r :使用拓展型正则表达式的语法
编辑命令中的选项参数:
p :打印指定的行
d :删除指定的行
s :字串替换,格式: “行范围s/原字符串/新字符串/g”
g :表示只要符合条件,全部进行处理
r :可以将另一个文件内容读取到文件中
w :可以将另一个文件内容覆盖到文件中
i :插入,在当前行上面插入一行或多行
a :插入,在当前行后面插入一行或多行
c :将选定行替换成指定内容
y :字符转换
[root@localhost ww]# sed -n 'p' /etc/passwd //打印文件所有内容,sed后一般跟-n结合,不加-n相当于把文件内容和缓冲中都打印,相当于打印两次
[root@localhost ww]# sed -n '3p' /etc/passwd //打印文件第三行内容
[root@localhost ww]# sed -n '1,3p' /etc/passwd //打印1到3行的内容
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ww]# sed -n '$p' /etc/passwd //打印最后一行内容
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
[root@localhost ww]# sed -n '1,+3p' /etc/passwd //打印第一行开始加3行内容
root:x:0:0:root:/root:/bin/bash
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
[root@localhost ww]# sed -n '/^$/p' 文件名 //打印空行
[root@localhost ww]# sed -n '/ /p' 文件名 //打印有空格的行
[root@localhost ww]# sed -n '/root/=' /etc/passwd //显示包含root行的行号
1
10
[root@localhost ww]# sed -n '$=' /etc/passwd //查看文件有多少行
56
[root@localhost ww]# sed -e '3q' /etc/passwd //输出前5行后退出
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# sed -n '1a hello world' /etc/passwd //在第一行后面添加一行为hello world
[root@localhost ~]# sed -n '3i hello' /etc/passwd //在第三行前面添加一行为hello
[root@localhost ~]# sed -n '3d' /etc/passwd //删除第三行
[root@localhost ~]# sed -n '2,4d' /etc/passwd //删除第2到第4行
[root@localhost ~]# sed -n '$d' /etc/passwd //删除最后一行
[root@localhost ~]# sed -n '/root/!d' /etc/passwd //删除不包含root的行
[root@localhost ~]# sed -n '/^root/d' /etc/passwd //删除以root开头的行
[root@localhost ww]# cat -n /etc/passwd | sed -n '1~8p' //从第一行开始每隔8行打印文件内容
1 root:x:0:0:root:/root:/bin/bash
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
17 libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
25 radvd:x:75:75:radvd user:/:/sbin/nologin
33 geoclue:x:992:986:User for geoclue:/var/lib/geoclue:/sbin/nologin
41 avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
49 username4:x:1005:1005::/home/username4:/bin/bash
[root@localhost ww]# cat -n /etc/passwd | sed -n 'p;n' //输出所有奇数行
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
………………………………
[root@localhost ww]# cat -n /etc/passwd | sed -n 'n;p' //输出所有偶数行
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
8 halt:x:7:0:halt:/sbin:/sbin/halt
10 operator:x:11:0:operator:/root:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
………………………………
[root@localhost ww]# cat -n /etc/passwd | sed -n '10,${n;p}' //输出从10行开始到结尾的奇数行
11 games:x:12:100:games:/usr/games:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
17 libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
19 rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
21 saslauth:x:995:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@localhost ww]# sed -n '/root\\|ntp/p' /etc/passwd //输出包含root或ntp的行,这里|时拓展正则,需要\\转义
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
[root@localhost ww]# sed -n '/root/p' /etc/passwd //输出包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ww]# sed -n '/root/Ip' /etc/passwd //不区分大小写显示含root的行
[root@localhost ww]# sed -nr '/root|ntp/p' /etc/passwd //输出包含root或ntp的行,不用\\转义|的话要在前面加r
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
[root@localhost ww]#sed 's/root//g' /etc/passwd //将文件中所有的root都删除
[root@localhost ww]#sed 's#/bin/bash#hello#p' /etc/passwd //将文件中的/bin/bash替换成hello。这里的#表示分隔符,可以换成@,逗号,或者\\
[root@localhost ww]#sed '/root/s/root/ROOT/g' /etc/passwd //将包含root行的root都替换成ROOT
[root@localhost ww]#sed 's/$/ABC/g' /etc/passwd //在每行的末尾添加ABC
[root@localhost ww]#sed '/root/s/^/#/g' /etc/passwd //在包含root的行开头添加#
[root@localhost ww]#sed '/root/w file2' /etc/passwd //将包含root的行写入file2中,覆盖写入
[root@localhost ww]#sed '1,5 {H;d};$G' /etc/passwd //将1到5行内容迁移到末尾
[root@localhost ~]# echo hello world gg | sed -nr 's/(hello) (world) (gg)/\\2 \\1 \\3/p'
world hello gg
##### 将hello和world换位打印,注意三个参数之间跟前面的一样有空格,后面的数字表示将前面的()整体对应的位置
[root@localhost ~]# echo hello world gg | sed -nr 's/(hello) (world)/\\1 the \\2/p'
hello the world gg
##### 在hello和world中插入the
[root@localhost ww]#set -i 's/^/#/' /etc/passwd //在每行开头添加#,直接修改源文件内容
[root@localhost ww]#set -i 's/^/#//' /etc/passwd //删除每行开头的#,直接修改源文件
[root@localhost ~]# vim sed.sh
#!/bin/sed -f
#在脚本中直接使用sed,这里的命令序列不用加单引号,每行最后一个字符不能存在其它字符
s/root/ROOT/g
s/\\/sbin\\/nologin/xxx/g
[root@localhost ~]# sed -f sed.sh pp.bak
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
bin:x:1:1:bin:/bin:xxx
daemon:x:2:2:daemon:/sbin:xxx
adm:x:3:4:adm:/var/adm:xxx
lp:x:4:7:lp:/var/spool/lpd:xxx
sync:x:5:0:sync:/sbin:/bin/sync
awk
格式 :awk 选项 命令部分
awk '{print}' 文件名 :打印文件所有内容
awk '{print "'$变量名'"}' :引入awk外部变量
内建变量
- NF :显示列数
- NR :显示行号
- $0 :处理整行内容
- $n :这里n是一个数字,表示处理第n列内容
- FS :指定分隔符
- OFS :指定输出时文本列之间的连接符
- RS :指定每行之间的分隔,如:RS : ,表示在冒号那里就会分行
- ORS :指定每行之间连接型
[root@localhost ~]# awk '{print}' pp.bak //打印文件所有内容,这里的pp.bak文件内容是复制/etc/passwd文件的前几行
root:x:0:0:root:/root:/bin/bash
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
sync:x:5:0:sync:/sbin:/bin/sync
- -F指定分隔符,$1表示打印第一列
[root@localhost ~]# awk -F: '{print $1}' pp.bak
root
bin
daemon
adm
lp
sync
[root@localhost ~]# awk -F: '{print $0}' pp.bak //$0表示打印整行
root:x:0:0:root:/root:/bin/bash
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
sync:x:5:0:sync:/sbin:/bin/sync
- 以冒号为分隔符打印第一列第二列
[root@localhost ~]# awk -F: '{print $1,$2}' pp.bak
root x
bin x
daemon x
adm x
lp x
sync x
- 用引号引起可以输出常量
[root@localhost ~]# awk -F: '{print $1"hhh"$2}' pp.bak
roothhhx
binhhhx
daemonhhhx
admhhhx
lphhhx
synchhhx
hhh
- 输出“用户名的uid是:”这里的用户名是变量,uid也是变量,用户名在第一列,uid在第三列
[root@localhost ~]# awk -F: '{print "用户名"$1"的uid是"$3}' pp.bak
用户名root的uid是0
用户名bin的uid是1
用户名daemon的uid是2
用户名adm的uid是3
用户名lp的uid是4
用户名sync的uid是5
- 以冒号为分隔符查看每行有多少列
[root@localhost ~]# awk -F: '{print NF}' pp.bak
7
7
7
7
7
7
[root@localhost ~]# awk -F: '{print $NF}' pp.bak
#### NF前加$表示显示最后一列,可以理解为先NF显示每行的列数,然后以这列数打印,就相当于打印每行的最后一列
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
- NR打印行号
[root@localhost ~]# awk -F: '{print NR}' pp.bak
1
2
3
4
5
6
[root@localhost ~]# awk -F: '{print NR,$0}' pp.bak //显示行号打印所有内容
1 root:x:0:0:root:/root:/bin/bash
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
[root@localhost ~]# awk -F: '{print NR"\\t"$0}' pp.bak // \\t表示制表符,也相当于tab键
1 root:x:0:0:root:/root:/bin/bash
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
- awk还可以增加条件判断
[root@localhost ~]# awk -F: '/^bin/{print}' pp.bak //打印以bin开头的,
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost ~]# awk -F: '/bin/{print}' pp.bak //打印包含bin的
root:x:0:0:root:/root:/bin/bash
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
sync:x:5:0:sync:/sbin:/bin/sync
[root@localhost ~]# awk -F: '$1~/bin/{print $NF}' pp.bak
#### 模糊匹配第一列里含bin的行并打印其最后一列,在~前面加!表示不匹配含bin的行
/sbin/nologin
[root@localhost ~]# awk -F: 'NR==1{print $NF}' pp.bak //打印第一行的最后一列
/bin/bash
[root@localhost ~]# awk -F: '$1=="lp"{print $NF}' pp.bak //打印第一列中包含lp的行的最后一列
/sbin/nologin
[root@localhost ~]# awk -F: 'NR~/3/{print NR,$0}' /etc/shadow //打印含3行号的内容
3 daemon:*:17834:0:99999:7:::
13 nobody:*:17834:0:99999:7:::
23 rtkit:!!:18779::::::
30 qemu:!!:18779::::::
31 tss:!!:18779::::::
32 usbmuxd:!!:18779::::::
33 geoclue:!!:18779::::::
34 ntp:!!:18779::::::
35 sssd:!!:18779::::::
36 setroubleshoot:!!:18779::::::
37 saned:!!:18779::::::
38 gdm:!!:18779::::::
39 gnome-initial-setup:!!:18779::::::
43 tcpdump:!!:18779::::::
- awk进行运算
[root@localhost ~]# awk 'BEGIN{print 1+1}'
2
[root@localhost ~]# awk 'BEGIN{print 2^3}'
8
[root@localhost ~]# awk 'BEGIN{print 2/3}'
0.666667
[root@localhost ~]# awk 'BEGIN{x=2;x++;print x}'
3
- awk指定分隔符
[root@localhost ~]# awk 'BEGIN{FS=":"}{print $1}' pp.bak
#### 这里的BEGIN表示开始,就是第一行与之前的开始,如果不加第一行就不会进行后面的命令序列,FS指定列的分隔符为冒号
root
bin
daemon
adm
lp
sync
[root@localhost ~]# awk 'END{print NR}' pp.bak
#### END表示执行命令序列的最后一个,这里表示从上往下显示行号,最后一个是6
6
[root@localhost ~]# awk 'BEGIN{FS=":";OFS="----"}{print $1,$2}' pp.bak //OFS指定打印的文本列之间的连接符
root----x
bin----x
daemon----x
adm----x
lp----x
sync----x
[root@localhost ~]# awk 'BEGIN{RS=":";ORS="----"}{print $2,$1,$0}' pp.bak
#### RS表示分行符,这里表示到冒号处就分行,ORS表示每行之间的连接符
root root---- x x---- 0 0---- 0 0---- root root---- /root /root----bin /bin/bash /bin/bash
bin---- x x---- 1 1---- 1 1---- bin bin---- /bin /bin----daemon /sbin/nologin /sbin/nologin
daemon---- x x---- 2 2---- 2 2---- daemon daemon---- /sbin /sbin----adm /sbin/nologin /sbin/nologin
adm---- x x---- 3 3---- 4 4---- adm adm---- /var/adm /var/adm----lp /sbin/nologin /sbin/nologin
lp---- x x---- 4 4---- 7 7---- lp lp---- /var/spool/lpd /var/spool/lpd----sync /sbin/nologin /sbin/nologin
sync---- x x---- 5 5---- 0 0---- sync sync---- /sbin /sbin---- /bin/sync /bin/sync
[root@localhost ~]# awk 'NR<3 || NR>5{print NR,$0}' pp.bak //打印行号小于3或大于5的行
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
[root@localhost ~]# awk 'NR>3 && NR<6{print NR,$0}' pp.bak //打印行号大于3且小于6的行
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
- awk的if语句
单分支 :if(){}
双分支 ;if(){}else{}
多分支 :if(){}else if(){}else{}
[root@localhost ~]# awk -F: '{if($3<4){print $0}}' pp.bak //如果第三列的uid小如4就打印
root:x:0:0:root:/root:/bin/bash
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
[root@localhost ~]# awk -F: '{if($3<4){print $0}else{print $1}}' pp.bak //在上面的基础上uid不小于4时打印第一列
root:x:0:0:root:/root:/bin/bash
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
sync
以上是关于Shell脚本----三剑客命令(grepsedawk)的主要内容,如果未能解决你的问题,请参考以下文章
shell脚本江湖秘籍只传有缘人——流编辑器“三剑客”之sed命令
Shell脚本三剑客——Grep(进阶版egrep)SedAwk命令