Linux三剑客:grep,awk 和 sed,从功能上来说分别对应了查找,分段,修改。
我们这里聚焦在分类、整理、统计上。
awk = “Aho Weiberger and Kernighan” 三个作者的姓的第一个字母,它是一种语言解析引擎。主要是过滤、分类、统计日志。
工作中常用的awk命令和含义
awk ‘BBEGIN{}END{}’ 程序开始和结束
awk ‘/Running/’ 正则匹配
awk ‘/aa/,/bb/’ 区间选择
awk ‘$2~/xxx/’ 字段匹配,这里指从第2个字段开始匹配包含xxx内容的行
awk ’NR==2’ 取第二行
awk ’NR>1’ 去掉第一行
awk的操作基于行,对于每一行又默认以空格分为多个列,行和列的分隔符可以修改。
awk的基本语法是 `awk 'pattern{action}' `,可以只有pattern或者action,只有pattern=打印pattern匹配的行们,只有action=对于每一行都执行这个action。
pattern可以有以下几种
BEGIN 执行匹配之前可以采取的action
END 执行匹配之后可以采取的action
BEGINFILE 读文件之前可以采取的action
ENDFILE 读文件之后可以采取的action
/regular expression/ 匹配每行正则表达式之后可以采取的action
pattern && pattern 且
pattern || pattern 或
pattern ? pattern : pattern 三目表达式
(pattern)
! pattern 非
pattern1, pattern2 范围表达式,对于第一个匹配pattern1到第一个匹配pattern2之间的行采取action
行操作pattern
模式 | 说明 |
NR==1 | 取出某一行 |
NR>=1 && NR>=5 | 取出1到5行 |
/oldboy/ | 取出有 oldboy 的行 |
/101/,/105/ | 取出 101-105 行 |
符号 | > < >= <= == != |
awk ‘$2~/xxx/’ 字段匹配,这里指从第2个字段开始匹配包含xxx内容的行
awk ’NR==2’ 取第二行
awk ’NR>1’ 去掉第一行
列操作pattern
-F | 指定分隔符,指定每一列结束标记(默认是空格,连续的空格,tab键) |
$数字 | 取出某一列,注意:在 awk 中 $ 内容一个意思,表示取出某一列 |
$0 | 整行的内容 |
{ptint xxx} | 取列的时候使用的选项 |
$NF | 表示最后一列 |
对于所有nginx进程发送信号12
样本数据
$ ps -ef|grep /opt/nginx/ |grep -v grep
root 109775 1 0 Oct21 ? 00:16:57 ./nginx
root 109776 1 0 Oct21 ? 00:15:04 ./nginx
root 196548 1 15 Oct19 ? 1-02:08:48 ./nginx
root 196567 1 12 Oct19 ? 21:12:28 ./nginx
我们需要拿到进程号,这里对于每一行,以空格作为分隔符,进程号处于第二列,我们先输出它,然后向他发送信号-12。
$ ps -ef|grep /opt/nginx/ |grep -v grep|awk '{print $2}'|xargs kill -12
对于上面的Nginx进程,找到以19开头的进程,发送信号50
我们要对第二列匹配以19开头的进程号,需要用到 $2 取第二列,然后用 pattern进行匹配
$ ps -ef|grep /opt/nginx/ |grep -v grep|awk '$2~/19[^ ]*/{print $2}'|xargs kill -50
附加题:对于19开头的进程进行 排序->去重->按数字的倒序显示
$ ps -ef|grep /opt/nginx/ |grep -v grep|awk '$2~/19[^ ]*/{print $2}'| sort | uniq -c | sort -nr
命令含义:
sort: 按从小到大进行排序
uniq -c :去重(相邻),还输出重复个数
-nr: 按数字进行倒叙排序
-n:按数字进行排序
利用awk给文本中每一行加上行号
样例文本自己生成
思路:awk运行前先定义序号索引0,用来递增保存用户,将用户提取出来,按索引分别保存, 切片结束后再按行数进行循环,将数字序号与第一步保存的信息拼接打印
使用命令
cat config.h_json |awk 'BEGIN{idx=0}{m[idx]=$0;idx++;}END{for(i=0;i
可圈可点的是这里的变量和数组都不用声明,就可以直接使用。
含义解释:
awk执行之前先idx=0
对于每一行都存入数组中,并且把idx+1
awk执行之后输出每一行和对应行号
统计域名中一级域名的出现次数
[root@shell ~]# cat url.txt
2 http: // www. etiantian. org/index.html
3 http: // www. etiantian. org/1.html
4 http: //post.etiantian. org/index.html
5 http: //mp3.etiantian. org/index.html
6 http: // www. etiantian.org/3.html
观察数据特征:
这里的一级域名是`www`和`post`等,他们出现的规律是`//`之后和`.`之前,按照`grep`正则表达式的方式也是可以抓出来的,但是会带着这俩特殊符号,还需要做正则表达式的提取,比较麻烦。我们这里要用awk,就需要分割列,这里的分隔符可以取`/`和`.`,然后一行就被分成了三个以上的部分: 前面 | 感兴趣的区域 | 后面balabala,然后就可以只打印出来感兴趣的区域,比较干净,然后 `sort + uniq -c` 即可
使用命令
awk -F [/.]+ '{print $2}' url.txt | sort | uniq -c
操作结果
$ awk -F [/.]+ '{print $2}' a|sort|uniq -c
3 www
1 mp3
1 post
使用命令2 ( 纯 awk )
awk -F [/.]+ '{arr[$2]++}END{for(i in arr) print i,arr[i]}' a
操作结果
$ awk -F [/.]+ '{arr[$2]++}END{for(i in arr) print i,arr[i]}' a
mp3 1
post 1
www 3
附加:排序 `sort -rnk2`
`-n` 字典序
`-k2` 以第二个字段作为key排序
`-r` 反向输出