Shell编程、part5
本节内容
1. 三剑客简介
2. sed命令详解
3. awk命令详解
文本处理三剑客
在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具:
| 命令 | 描述 |
| grep | 默认不支持扩展表达式,加-E 选项开启 ERE。如果不加-E 使用花括号要加转义符\{\} |
| egrep | 支持基础和扩展表达式 |
| awk | 支持 egrep 所有的正则表达式 |
| sed | 默认不支持扩展表达式,加-r 选项开启 ERE。如果不加-r 使用花括号要加转义符\{\} |
sed详解
1. 前言
我们都知道,在Linux中一切皆文件,比如配置文件,日志文件,启动文件等等。如果我们相对这些文件进行一些编辑查询等操作时,我们可能会想到一些vi,vim,cat,more等命令。但是这些命令效率不高,而在linux中有三种工具:顶配awk,中配sed,标配grep。使用这些工具,我们能够在达到同样效果的前提下节省大量的重复性工作,提高效率。
文件内容可以是来自文件,也可以直接来自键盘或者管道等标准输入,最后的结果默认情况下是显示到终端的屏幕上,但是也可以输出到文件中。
编辑文件也是这样,以前我们修改一个配置文件,需要移动光标到某一行,然后添加点文字,然后又移动光标到另一行,注释点东西…….可能修改一个配置文件下来需要花费数十分钟,还有可能改错了配置文件,又得返工。这还是一个配置文件,如果数十个数百个呢?因此当你学会了sed命令,你会发现利用它处理文件中的一系列修改是很有用的。只要想到在大约100多个文件中,处理20个不同的编辑操作可以在几分钟之内完成,你就会知道sed的强大了。
2. 语法格式
sed [选项] [sed命令] [输入文件]
说明:
1,注意sed软件以及后面选项,sed命令和输入文件,每个元素之间都至少有一个空格。
2,sed -commands(sed命令)是sed软件内置的一些命令选项,为了和前面的options(选项)区分,故称为sed命令
3,sed -commands 既可以是单个sed命令,也可以是多个sed命令组合。
4,input -file (输入文件)是可选项,sed还能够从标准输入如管道获取输入。
3. sed的工作原理
sed读取一行,首先将这行放入到缓存中
然后,才对这行进行处理
处理完成以后,将缓冲区的内容发送到终端
存储sed读取到的内容的缓存区空间称之为:模式空间(Pattern Space)
4. 选项说明
option[选项] | 解释说明(带*的为重点) |
---|---|
-n (no) | 取消默认的sed软件的输出,常与sed命令的p连用。* |
-e (entry) | 一行命令语句可以执行多条sed命令 * |
-r (ruguler) | 使用扩展正则表达式,默认情况sed只识别基本正则表达式 * |
-i (inside) | 直接修改文件内容,而不是输出到终端,如果不使用-i选项sed软件只是修改在内存中的数据,并不会影响磁盘上的文件* |
sed -commands[sed命令] | 解释说明(带*的为重点) |
---|---|
a (append) | 追加,在指定行后添加一行或多行文本 * |
c (change) | 取代指定的行 |
d (delete) | 删除指定的行 * ` |
i (insert) | 插入,在指定行前添加一行或多行文本 * |
p (print) | 打印模式空间内容,通常p会与选项-n一起使用* |
特殊符号 | 解释说明(带*的为重点) |
---|---|
! | 对指定行以外的所有行应用命令* |
sed.增.删.改.查
1. 增
这里我们需要用到2个sed命令,分别是:
- “a”:追加文本到指定行后,记忆方法:a的全拼是apend,意思是追加。
- “i“:插入文本到指定行前,记忆方法:i的全拼是insert,意思是插入。
实例1:a
[root@ken ~]# sed "2a 这是新添加的一行" test
this is the first line
this is the second line
这是新添加的一行
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
- 2代表指定对第2行操作,其他的行忽略
- a代表插入的意思,2i即在第2行前插入文本
- 2a后面加上空格,然后跟上你想要插入的文本即可
实例2:i
[root@ken ~]# sed "2i 我又新添加了一行" test
this is the first line
我又新添加了一行
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
实例3:同时增加多行(/n)
[root@ken ~]# sed "2i 这是第一条记录\n这是第二条记录\n这是第三条记录" test
this is the first line
这是第一条记录
这是第二条记录
这是第三条记录
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
2.删
- 这个功能也是非常得有用,比如我们想删除文件中的某些行,以前最常用的是vi或vim命令,但现在我们知道了sed命令,就应该使用这个高逼格的命令完成任务了。
- “d”:删除文本,记忆方法:d的全拼是delete,意思是删除。
- sed软件可以对单行或多行文本进行处理。如果在sed命令前面不指定地址范围,那么默认会匹配所有行。
实例1:删除所有的行
[root@ken ~]# cp test{,.bak}
[root@ken ~]# sed 'd' test
命令说明:如果在sed命令前面不指定地址范围,那么默认会匹配所有行,然后使用d命令删除功能就会删除这个文件的所有内容
实例2:删除指定的行
[root@ken ~]# cat test.bak >test
[root@ken ~]# sed '2d' test
this is the first line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
实例3:删除指定范围行
[root@ken ~]# sed '2,5d' test
this is the first line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
实例4:删除匹配的行
[root@ken ~]# sed '/sixth/d' test
this is the first line
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
命令说明:在sed软件中,使用正则的格式和awk一样,使用2个”/“包含指定的正则表达式,即“/正则表达式/”。
实例5:删除指定行到行尾的内容
[root@ken ~]# sed '2,$d' test
this is the first line
第二行也会被删掉
实例6:取反
一、
[root@ken ~]# sed '2,3!d' test
this is the second line
this is the third line
二、
[root@ken ~]# sed '/tenth/!d' test
this is the tenth line
3.改
- “c”:用新行取代旧行,记忆方法:c的全拼是change,意思是替换。
[root@ken ~]# sed '2c 改过之后的第二行' test
this is the first line
改过之后的第二行
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
this is sixth line
文本替换
- 接下来说的这个功能,有工作经验的同学应该非常的熟悉,因为使用sed软件80%的场景就是使用替换功能。
- 这里用到的sed命令,选项:
“s”:单独使用–>将每一行中第一处匹配的字符串进行替换==>sed命令
“g”:每一行进行全部替换–>sed命令s的替换标志之一(全局替换),非sed命令。
“-i”:修改文件内容–>sed软件的选项,注意和sed命令i区别。
sed软件替换模型
sed -i ‘s/目标内容/替换内容/g’ ken.log
sed -i ‘s#目标内容#替换内容#g’
实例1:
[root@ken ~]# sed 's/line/hang/g' test
this is the first hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang
命令说明:从上面命令的结果我们就知道sed命令默认不会修改文件的内容
实例2:
[root@ken ~]# sed -i 's/line/hang/g' test
[root@ken ~]# cat test
this is the first hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang
命令说明:如果想真正的修改文件内容,我们就需要使用选项“-i”,这个要和sed命令“i”区分开来。同时我们可以发现命令执行后的结果是没有任何输出的。
4.查
- 这个功能也是非常得有用,比如我们想查看文件中的某些行,以前最常用的是cat或more或less命令等,但这些命令有些缺点,就是不能查看指定的行。而我们用了很久的sed命令就有了这个功能了。而且我们前面也说过使用sed比其他命令vim等读取速度更快!
- 这里我们需要用到1个sed命令
- “p”:输出指定内容,但默认会输出2次匹配的结果,因此使用-n选项取消默认输出,记忆方法:p的全拼是print,意思是打印。
实例1:
[root@ken ~]# sed '2p' test
this is the first hang
this is the second hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang
[root@ken ~]# sed -n '2p' test
this is the second hang
实例2:
[root@ken ~]# sed -n '2,5p' test
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
实例3:
[root@ken ~]# sed -n '/ninth/p' test
this is the ninth hang
补充:-e多点操作
实例1:
[root@ken ~]# sed -e '2d' -e '5d' test
this is the first hang
this is the third hang
this is the forth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang
实例2:
[root@ken ~]# sed -n -e '2p' -e '5p' test
this is the second hang
this is the fivth hang
删除注释行和空白行
第一种方法:
[root@ken ~]# cp test{,.bak}
[root@ken ~]# ls
anaconda-ks.cfg a.out ken1 test test1 test2 test.bak test.txt
[root@ken ~]# grep -v -E “(^$)|(^#)” test.bak
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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@ken ~]# grep -v -E “(^$)|(^#)” test.bak > test
[root@ken ~]# cat test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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@ken ~]# sed -i -e ‘/^$/d’ -e ‘/^#/d’ test.bak
[root@ken ~]# cat test.bak
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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
sed用法总结
1.查找指定的字符串
例子:显示/etc/passwd中保含root的行(显示模式空间中的内容)
方法1:set '/root/p' /etc/passwd
方法2:cat /etc/passwd | sed '/root/p'
2.在指定的位置做增删
例子:删除以root为开头的行
# sed ‘/^root/d’ a.txt
例子:在包含root的行后添加一行 i am ken
# sed ‘/root/a i am ken’ a.txt
3.按行替换
例子:将5到9行的内容替换为 i am ken
# sed ‘5,9c i am ken’ a.txt
4.按照字符替换
例子:将/etc/selinux/config中的SELINUX=enforcing改成 disabled
写法1:# sed -i ‘s/SELINUX=disabled/SELINUX=enforcing/g’ config
写法2:# sed -r -i ‘s/(SELINUX=)disabled/\1enforcing/g’ config
5.查找指定的内容再做替换
例子:将以r开头的行中的oo替换为qq
# sed ‘/^r/{s/oo/qq/g}’ passwd
6.多点编辑
例子:去除文件中的注释行和空白行
# grep -v -E “(^#)|(^$)” passwd.bak >passwd
# cat passwd.bak | sed -e ‘/^#/d’ -e ‘/^$/d’ >passwd
7)取反操作
显示非1-3行
# sed -n ‘1,3!p’ passwd
awk详解
awk不仅仅时linux系统中的一个命令,而且是一种编程语言,可以用来处理数据和生成报告(excel)。处理的数据可以是一个或多个文件,可以是来自标准输入,也可以通过管道获取标准输入,awk可以在命令行上直接编辑命令进行操作,也可以编写成awk程序来进行更为复杂的运用。
awk的格式
- awk指令是由模式,动作,或者模式和动作的组合组成。
- 模式既pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR==1,这就是模式,可以把他理解为一个条件。
- 动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。比如awk使用格式:
awk处理的内容可以来自标准输入(<),一个或多个文本文件或管道。
- pattern既模式,也可以理解为条件,也叫找谁,你找谁?高矮,胖瘦,男女?都是条件,既模式。
- action既动作,可以理解为干啥,找到人之后你要做什么。
模式和动作的详细介绍我们放在后面部分,现在大家先对awk结构有一个了解。 - 分析awk处理过程:
读取文本第一行,首先会和匹配模式进行相匹配,如果发现第一行内容不和模式相匹配的话,就继续读取下一行
读取到第二行发现和模式相匹配,就会执行花括号里面的动作
然后继续读取下一行,发现和模式相匹配,就会执行花括号里面的动作
...
依次读取全文
awk参数
-F:指定分隔符
几个小概念
记录(record):一行就是一个记录
分隔符(field separator):进行对记录进行切割的时候所使用的字符
字段(field):将一条记录分割成的每一段
FILENAME:当前处理文件的文件名
FS(Field Separator):字段分隔符(默认是以空格为分隔符=)
NR(Number of Rrecord):记录的编号(awk每读取一行,NR就加1==)
NF(Number of Field):字段数量(记录了当前这条记录包含多少个字段==)
ORS(Output Record Separator):指定输出记录分隔符(指定在输出结果中记录末尾是什么,默认是\n,也就是换行)
OFS(Output Field Separator):输出字段分隔符
RS:记录分隔符
输出字段的表示方式
$1 $2 … $n 输出一个指定的字段
$NF 输出最后一个字段
$0 输出整条记录
awk执行过程
[root@ken ~]# awk 'NR>=2&&NR<=5{print $0}' /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
命令说明: 条件NR>=2,表示行号大于等于2时候,执行{print $0}显示整行。 awk是通过一行一行的处理文件,这条命令中包含模式部分(条件)和动作部分(动作),awk将处理模式(条件)指定的行
1)awk读入第一行内容
2)判断是否符合模式中的条件NR>=2
a,如果匹配则执行对应的动作{print $0}
b,如果不匹配条件,继续读取下一行
3)继续读取下一行
4)重复过程1-3,直到读取到最后一行(EOF:end of file)
准备测试文件
[root@ken ~]# head /etc/passwd > test
[root@ken ~]# cat test
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
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
实例1:打印行号
[root@ken ~]# awk '{print NR,$0}' test
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
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
实例2:输出有多余5个字段的行的第三个字段
[root@ken ~]# awk -F ':' 'NF>=5{print $3}' test
0
1
2
3
4
5
6
7
8
11
实例3:输出每行行号和该行有几个字段
[root@ken ~]# awk -F ':' '{print NR,NF}' test
1 7
2 7
3 7
4 7
5 7
6 7
7 7
8 7
9 7
10 7
例子4:打印出来用户名以及对应的shell类型
[root@ken ~]# awk -F “:” ‘{print $1,$NF}’ test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
i#adm /sbin/nologin
lp /sbin/nologin
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
[root@ken ~]# awk -F “:” ‘{print $1,$7}’ test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
i#adm /sbin/nologin
lp /sbin/nologin
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
awk进阶–正则
- 正则表达式的运用,默认是在行内查找匹配的字符串,若有匹配则执行action操作,但是有时候仅需要固定的列来匹配指定的正则表达式,比如:我想取/etc/passwd文件中第五列{$5}这一列查找匹配mail字符串的行,这样就需要用另外两个匹配操作符,并且awk里面只有这两个操作符来匹配正则表达式。
实例1:匹配整行
[root@ken ~]# awk '/^root/' test
root:x:0:0:root:/root:/bin/bash
和下面的效果是一样的
[root@ken ~]# awk '$0~/^root/' test
root:x:0:0:root:/root:/bin/bash
注意:awk只用正则表达式的时候是默认匹配整行的即‘$0~/root/’和‘/root/’是一样的。
实例2:匹配一行中的某一列
[root@ken ~]# awk -F ':' '$5~/root/' test
root:x:0:0:root:/root:/bin/bash
提示:
- $5表示第五个区域(列)
- ~表示匹配(正则表达式匹配)
- /root/表示匹配root这个字符串
$5~/root/表示第五个区域(列)匹配正则表达式/root/,既第5列包含root这个字符串,则显示这一行。
实例3:匹配行尾为sync
[root@ken ~]# awk -F ':' '/sync$/{print $0}' test
sync:x:5:0:sync:/sbin:/bin/sync
实例4:显示名字和登录类型
[root@ken ~]# awk -F ':' '{print $1,$NF}' test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
$NF:表示匹配的末尾部分,这里也可以写成$7
实战: 取出网卡IP地址(企业面试题)
[root@ken ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 00:0c:29:99:ea:a6 brd ff:ff:ff:ff:ff:ff
inet 172.20.10.6/24 brd 172.20.10.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 2408:84f4:86:47e1:20c:29ff:fe99:eaa6/64 scope global mngtmpaddr dynamic
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe99:eaa6/64 scope link
valid_lft forever preferred_lft forever
第一种方法:
[root@ken ~]# ip a | awk -F ' +' 'NR==9{print $3}' | awk -F '/' '{print $1}'
172.20.10.6
第二种方法:
[root@ken ~]# ip a | grep -E '^ +.*inet\>.*' | awk -F ' +|/' 'NR==2{print $3}'
172.20.10.6
第三种方法:
[root@ken ~]# hostname -i | awk -F ' ' '{print $3}'
172.20.10.6
第四种方法:
[root@ken ~]# ip a | grep brd.*glo | awk -F ' +|/' '{print $3}'
172.20.10.6
第五种方法:
[root@ken ~]# ip a | grep "scope" | awk 'NR==3{print $0}' | awk -F "( |/)+" '{print $3}'
172.20.10.6
方法还有很多很多,大家如果对自己有高要求的话,要至少写出来十种以上的方法哦!
awk特殊模式-BEGIN模式与END模式
- BEGIN模块再awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS)
- 需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在输入文件进行任何处理前先执行BEGIN里的动作(action)。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等值。
BEGIN模块
实例1:
[root@ken ~]# ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $3}'
172.20.10.6
[root@ken ~]# ifconfig eth0 | awk -F "[^0-9.]+" 'NR==2{print $2}'
172.20.10.6
#上面的也可以写成
[root@ken ~]# ifconfig eth0 | awk 'BEGIN{FS="[ :]+"}NR==2{print $3}'
172.20.10.6
[root@ken ~]# ifconfig eth0 | awk 'BEGIN{FS="[^0-9.]+"}NR==2{print $2}'
172.20.10.6
实例2:在读取文件之前,输出些提示性信息(表头)。
[root@ken ~]# awk -F ':' 'BEGIN{print "username","bash type"}{print $1,$NF}' test
username bash type
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
END模块
EHD在awk读取完所有的文件的时候,再执行END模块,一般用来输出一个结果(累加,数组结果),也可以是和BEGIN模块类似的结尾标识信息与BEGIN模式相对应的END模式,格式一样,但是END模式仅在awk处理完所有输入行后才进行处理。
实例1:
[root@ken ~]# awk -F ':' 'BEGIN{print "username","bash type"}{print $1,$NF}END{print "end of file"}' test
username bash type
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
end of file
实例2:统计包含root的行的数量
方法一:
[root@ken ~]# cat test | grep root| wc -l
2
方法二:
[root@ken ~]# cat test | grep -c root
2
方法三:
[root@ken ~]# cat /etc/passwd | awk 'BEGIN{i=0}/root/{i++}END{print i}'
2
[root@ken ~]# cat /etc/passwd | awk '/root/{i++}END{print i}'
2
总结awk执行过程
回顾一下awk的结构
awk -F 指定分隔符 ‘BRGIN{}END{}’,如下图
awk数组
数组构成:
数组名[元素名]=值
如图不难发现,awk数组就和酒店一样。数组的名称就像是酒店名称,数组元素名称就像酒店房间号码,每个数组元素里面的内容就像是酒店房间里面的人。
实战:统计域名出现的次数(百度和搜狐面试题)
[root@ken ~]# cat test
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
方法一:
[root@ken ~]# cat test | awk -F '/+' '{print $2}' | sort | uniq -c
7 www.qq.com
13 www.sina.com
25 www.taobao.com</pre>
方法二:
[root@ken ~]# cat test | awk -F '/+' '{h[$2]++}END{for (i in h) print i,h[i]}'
www.sina.com 13
www.qq.com 7
www.taobao.com 25
awk用法总结
1. **结合内置变量,打印指定的几行,以及字段数量**
例子;输出有多余5个字段的行的第三个字段
# cat a.sh | awk -F “:” ‘NF>=5{print $3}’
例子:输出每行行号和该行有几个字段
# cat a.sh | awk -F “:” ‘{print NR,NF}’
例子:输出用户名,要求所有用户显示在同一行,而且用空格分隔
# cat mypwd | awk ‘BEGIN{FS=”:”; ORS=” “}{print $1}’
2. **结合正则来匹配一行或者某个字段**
例子:输出用户名以s为开头的用户的uid
# cat mypwd | awk -F “:” ‘/^s/{print $}’
例子:输出第五个字段是以t为结尾的用户的姓名
# cat mypwd | awk -F “:” ‘$5~/t$/{print $1}’
3. **采用比较符号来进行打印指定的某些行**
例子:实现仅仅输出3-5的内容,每行前面添加一个行号
# cat mypwd | awk ‘NR>=3&&NR<=5{print NR,$1}’
或
# cat mypwd | awk ‘NR==3,NR==5{print NR,$1}’
例子:实现仅仅输出3 和 5 和 7行的内容,每行前面添加一个行号
# cat mypwd | awk ‘NR==3||NR==5||NR==7{print NR,$1}’
4. **END**
例子:统计mypwd中以#开头的行有多少行
# cat mypwd | awk ‘BEGIN{n=0}/^#/{n+=1}END{print n}’
统计:mypwd中,以:为分隔符,字段数量在3-5的行的数目
# cat mypwd | awk ‘BEGIN{FS=”:”}NF>=3&&NF<=5{n+=1}END{print n}’
5. **ip**
例子:统计IP
[root@ken]# cat url.txt | awk -F “/+” ‘{urls[$2]++}END{for(key in urls)print key, urls[key]}’
www.baidu.com 12
haha.baidu.com 1
ftp.baidu.com 6
mail.baidu.com 7
Shell编程、part5的更多相关文章
- Linux学习笔记(17) Shell编程之基础
1. 正则表达式 (1) 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式:通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find ...
- shell编程:定义简单标准命令集
shell是用户操作接口的意思,操作系统运行起来后都会给用户提供一个操作界面,这个界面就叫shell,用户可以通过shell来调用操作系统内部的复杂实现,而shell编程就是在shell层次上进行编程 ...
- Linux Shell编程入门
从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操 ...
- Shell编程菜鸟基础入门笔记
Shell编程基础入门 1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...
- Linux_10------Linux之shell编程------变量
.-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...
- 需要交互的shell编程——EOF(转载)
在shell编程中,”EOF“通常与”<<“结合使用,“<<EOF“表示后续的输入作为子命令或子shell的输入,直到遇到”EOF“, 再次返回到主调shell,可将其理解为分 ...
- ****CodeIgniter使用cli模式运行,把php作为shell编程
shell简介 在计算机科学中,Shell俗称壳(用来区别于核).而我们常说的shell简单理解就是一个命令行界面,它使得用户能与操作系统的内核进行交互操作. 常见的shell环境有:MS-DOS.B ...
- Shell 编程基础之变量和环境变量
一.变量赋值和引用 Shell 编程中,使用变量无需事先声明,同时变量的命名不惜遵循如下规则: 首个字符必须为字母(a-z,A-Z)或者_ 变量名中间不能有空格,可以使用_连接 不能使用其他表达符号 ...
- Linux Shell编程基础
在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls 显示当前路径下的文件,常用的有 -l 显示长格式 -a 显示所有包括隐 ...
- centos 下建用户 shell编程
useradd 用户名 passwd 用户名 cat /etc/passwd 查看用户信息 删除用户 userdel -r 加一个 -r 表示把用户及用户的主目录都删除 su 切换用户 sud ...
随机推荐
- 拒绝被坑!如何用Python和数据分析鉴别刷单!?
发际线堪忧的小Q,为了守住头发最后的尊严,深入分析了几十款防脱洗发水的评价,最后综合选了一款他认为最完美的防脱洗发水. 一星期后,他没察觉到任何变化. 一个月后,他用卷尺量了量,发际线竟然后退了0.5 ...
- 一个原生ajax在jetbrains开发平台的调用方法
这段随笔的记述目的无非是,一个html页面中可能有多段js代码,所以采用外引的方法应该会好一些 function checkfiles() { var xhr = new XMLHttpRequest ...
- 31.整数中1出现的次数(从1到n整数中1出现的次数)
题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...
- Javascript兼容各浏览器的日期转换
var date = new Date(Date.parse("2015-09-05".replace(/-/g,"/")));'2015-09-05'是无法被 ...
- Nowcoder Two Graphs ( 图的同构 )
题目链接 题意 : 给出两幅顶点数一样的图 G1.G2 ,现在要求在 G2 中选出一些边集.使之构成一幅新的图 G ,要求 G 要与 G1 同构,现在要你统计合法的 G 有多少种 分析 : 图的同构 ...
- 【PKUSC2019】树染色【线段树合并】【树形DP】
Description 给出一棵n个点的树,现在有m种颜色,要给每个节点染色,相邻节点不能同色. 另外有k条限制,形如x号点不能为颜色y 同一节点有可能有多条限制. 求方案数对998244353取模的 ...
- Makefile样例
Makefile1 src = $(wildcard ./*cpp) obj = $(patsubst %.cpp, %.o,$(src)) target = test $(target) : $(o ...
- Android 一般动画animation和属性动画animator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- AcWing:110. 防晒(贪心)
有C头奶牛进行日光浴,第i头奶牛需要minSPF[i]到maxSPF[i]单位强度之间的阳光. 每头奶牛在日光浴前必须涂防晒霜,防晒霜有L种,涂上第i种之后,身体接收到的阳光强度就会稳定为SPF[i] ...
- JSP中解决session超时跳转到登陆页面并跳出iframe框架或局部区域的方法
当session会话超时,页面请求被重新定位到了登陆界面.但登录界面在iframe中的解决方案:在登录页面中加入下面的js代码: <script type="text/javascri ...