知识点
grep sed awk
grep
操作对象是一个文件的关键词,确定这个关键词,然后显示的时候附加参数(反显示,同时显示上下几行,显示时增加行号)。 选项
- c 行数 跟wc-l差不多
- i 不区分大小写 find -iname
- n 显示行号 set nu
- v 取反
- An 过滤符合的行以及下面n行
- Bn 过滤符合的行以及上面n行
- Cn 过滤符合的行以及上下n行
- r 过滤所有子目录
[root@localhost awk]# grep mail -c awk.txt
1
[root@localhost awk]# grep h -in awk.txt
1:root:x:0:0:root:/root:/bin/bash
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
18:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
19:chrony:x:998:996::/var/lib/chrony:/sbin/nologin
20:www:x:1000:1000::/home/www:/bin/bash
21:Huawei12#$:22222
[root@localhost awk]# grep [^z-k] -n awk.txt
grep: Invalid range end //不能识别反序.
[root@localhost awk]# grep [^k-z] -n awk.txt
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
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
[root@localhost awk]# grep H -A5 awk.txt
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin //不够5行...
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
www:x:1000:1000::/home/www:/bin/bash
Huawei12#$:22222
# cci jumsss:1111
1a
2b
3c
9d
[root@localhost awk]# grep emd -B3 awk.txt
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
[root@localhost awk]# grep emd -C3 awk.txt
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:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
grep 配合正则符号
- [^] 代表非括号中的字符
- ^[] 代表以括号中的字符开头
- . 代表一个字符
- * 代表*前面出现的次数(0-n)
- {} 里面的数字代表前面字符出现的次数
- + 代表+前面出现的次数(1-n)
- ? 代表?前面出现的次数(0-1)
- | 代表逻辑或
==*>+>{}>?==
[root@localhost awk]# grep ^root -n awk.txt
1:root:x:0:0:root:/root:/bin/bash
[root@localhost awk]# grep ^[0-9] -n awk.txt
23:1a
24:2b
25:3c
26:9d
27:0u
28:4545h
[root@localhost awk]# grep '.*' -n awk.txt //过滤所有,匹配所有
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
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
[root@localhost awk]# grep 'r.t' awk.txt
operator:x:11:0:operator:/root:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
当关键字里有特殊符号的时候要用\将字符脱衣,或者使用egrep扩展。
[root@localhost awk]# grep '0{2}' awk.txt
[root@localhost awk]# grep '0\{2\}' awk.txt
games:x:12:100:games:/usr/games:/sbin/nologin
www:x:1000:1000::/home/www:/bin/bash
[root@localhost awk]# egrep '0{2}' awk.txt
games:x:12:100:games:/usr/games:/sbin/nologin
www:x:1000:1000::/home/www:/bin/bash
sed
stream editor for filtering and transforming text,具有过滤和转换文档的能力。相比与grep的filtering多了一个transforming的能力!
sed格式为:sed -n 'n'p xxoo.txt, -n代表只显示我们过滤到的,'n'代表第几行。
[root@localhost awk]# sed -n '3'p awk.txt //把第三行打印出来
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost awk]# sed -n '1,3'p awk.txt //打印1-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
[root@localhost awk]# sed -e '1'p -ne '3'p awk.txt //-e可以连续操作
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
打印包含某些关键字的行(跟grep的用法就差不多了)
[root@localhost awk]# sed -n '/root/'p awk.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost awk]# sed -n 'root'p awk.txt //如果是过滤关键字的话最好使用//,不然没效果!
[root@localhost awk]# sed -n '/^[0-9]/'p awk.txt
1a
2b
3c
9d
0u
4545h
[root@localhost awk]# sed -n '/h.t/'p awk.txt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
[root@localhost awk]# sed -n '/h..t/'p awk.txt
halt:x:7:0:halt:/sbin:/sbin/halt
删除某行
[root@localhost awk]# chattr +i awk.txt
[root@localhost awk]# lsattr awk.txt
----i----------- awk.txt
[root@localhost awk]# sed '1,20'd awk.txt //删除1-20行,没有实际删除。
Huawei12#$:22222
# cci jumsss:1111
1a
2b
3c
9d
0u
4545h
[root@localhost awk]# sed -i '1,20'd awk.txt //加上-i选项就可以直接对文件进行真正的删除操作!
sed: 无法重命名 ./sedFOGCio:不允许的操作
[root@localhost awk]# chattr -i awk.txt
[root@localhost awk]# sed -i '1,20'd awk.txt
[root@localhost awk]# cat awk.txt
Huawei12#$:22222
# cci jumsss:1111
1a
2b
3c
9d
0u
4545h
替换关键字
[root@localhost awk]# sed '1,2s/bash/nologin/g' sed.txt //1,2行的bash换成nologin,s代表替换,g代表全局
root:x:0:0:root:/root:/bin/nologin
[root@localhost awk]# sed 's/[a-z]//g' sed.txt //所有字母都替换成空
::0:0::/://
::1:1::/://
::2:2::/://
::3:4:://://
::4:7::///://
::5:0::/://
[root@localhost awk]# sed 's/[0-9]//g' sed.txt //所有数字都替换成空
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
lp:x:::lp:/var/spool/lpd:/sbin/nologin
sync:x:::sync:/sbin:/bin/sync
调座位
[root@localhost awk]# grep root sed.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost awk]# sed -r 's/(root)(.*)(bash)/\3\2\1/' sed.txt //加上-r就不用敲脱衣字符了。
bash:x:0:0:root:/root:/bin/root
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
小结:
-n,p为打印指定行数,关键字用'//',s为替换,g为全局,-i这不是演习,-e多连击,-r脱衣
awk
一个比sed更加强大的命令,
打印某一段
[root@localhost awk]# awk -F ':' '{print $1}' www.txt //-F ':'指定以:为分隔符如果不指定分隔符那系统就识别不出哪个为第一第二段,所以是不是可以理解只要有$n 就必有-F呢? $1为第一段 相应的$2为第二段 但是$0为整行
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
...
过滤关键字,跟grep就差不多了,但是比grep更加强大!
[root@localhost awk]# awk '/root/' www.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost awk]# awk -F':' '$1 ~/oo/' www.txt //~代表匹配的意思
root:x:0:0:root:/root:/bin/bash
条件操作符
awk中可以使用逻辑符号进行判断:==、>、>=、<、!=、&&、||。
以==数字的时候直接写数字,如果给数字加上“”则会被认定为字符。所以后面如果跟的是字符则需加上“”
[root@localhost test]# awk -F':' '$3==0' www.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost test]# awk -F ':' '$3>=666' www.txt
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
panda:x:1000:3333::/home/panda:/bin/bash
www:x:1001:1001::/home/www:/bin/bash
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost test]# awk -F ':' '$7!="/sbin/nologin"' www.txt
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
panda:x:1000:3333::/home/panda:/bin/bash
www:x:1001:1001::/home/www:/bin/bash
[root@localhost test]# awk -F ':' '$7=="/sbin/nologin" && $3>=666' www.txt //&&的使用
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost test]# awk -F ':' '$3>=1000 || '/sshd/'' www.txt
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
panda:x:1000:3333::/home/panda:/bin/bash
www:x:1001:1001::/home/www:/bin/bash
awk的内置变量
awk常用变量有OFS,NF和NR。其中OFS和-F差不多个人感觉有填充的意思。NF是统计一行有多少段,个人感觉应该要跟-F搭伙,而$NF的意思则为最后一段的值($)。
[root@localhost test]# head -3 www.txt |awk -F ':' '{OFS="^"} {print $1,$5,$6}'
root^root^/root
bin^bin^/bin
daemon^daemon^/sbin
[root@localhost test]# awk -F ':' '{OFS="#"}{if ($3>999) {print $1,$2,$3,$4}}' /etc/passwd //字符太多了,有没有什么规律啊!
panda#x#1000#3333
www#x#1001#1001
[root@localhost test]# head -n3 /etc/passwd | awk -F ':' '{print NF}'
7
7
7
[root@localhost test]# head -n3 /etc/passwd | awk -F ':' '{print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
NR是统计文件有多少行的,他和FNR配合可以将2个文件合并起来。当NR==FNR为真的时候,实际上是匹配到第一个文件。当NR==FNR不为真的时候匹配到第二个文件!
awk -F ':' 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' file1 file2
替换字符
[root@localhost test]# head -n3 www.txt|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@localhost test]# awk -F ':' '{(a=a+$3)};END{print a}' www.txt //END代表所有的行都已经执行!
5603
- grep -n '/key words/' file1
- grep '正则' file1
- sed -n 'n'p file1 打印第n行 n1,n2
- sed -n 'key words'p file1 打印关键字行
- sed -e 'n'p -e 'key words'p -n file1 上面1+2连击
- sed 'n'd file1 删除第n行 这是演习
- sed '(n1,n2)s/words1/words2/g' file1 替换字符
- sed -r 's/(a)(b)(c)/\3\2\1/' file1 换座位
- sed -i 's/a/b/g' file1 替换a为b 这不是演习
- awk -F ':' '{print $n}' file 打印第n段
- awk '/key words/' file1 过滤关键字
- awk -F ':' '$n==n' file1 匹配第n行为n的那一行(还有>,<,!=,&&,||)
- awk -F ':' '{OFS="#"}{if ($n>1000){print $a,$b,$c}}' file1 满足第n列>1000的,打印abc列并用#分隔
- awk -F ':' '{print NF}' file1 打印一行有多少列,$NF为最后一段。
- awk -F ':' '{print NR}' file1 打印有多少行,配合FNR可以将file1和file2合并。
- awk -F ':' '$n="a"' file1 替换第n行为字符为a