首页 > 系统相关 >Linux-awk

Linux-awk

时间:2024-07-16 15:29:56浏览次数:13  
标签:2052744 passwd etc awk Linux print root

awk

3.4.2 功能

过滤	取行  取列  统计计算 数组  函数

3.4.3 格式

awk 条件  动作  (找谁 干啥)
awk [options] 'commands' filenames 
awk [options] -f awk-script-file filenames

3.4.4 awk处理数据的方式:

1、进行逐行扫描文件,从第一行到最后一行
2、寻找匹配的特定模式的行,在行上进行操作
3、如果没有指定处理动作,则把匹配的行显示到标准输出
4、如果没有指定模式,则所有被操作的行都被处理
要点:awk里面不会默认输出,需要加print进行输出

3.4.5 参数:

print	-----打印输出内容
	在awk里满足条件之后默认执行的工作时(print $0)显示内容
$n		-----取第n列内容
$0		-----一整行内容
$NF		-----最后一列
NR		-----记录输出文件的编号(行号)
FNR		-----当前输入文件的编号(行号)
NR==n	-----第n行
NF		-----统计文件列数
-F(FS)-----创建分隔符,字段分隔符
	在awk里默认的分隔符为单个空格 连续空格 tab键
-RS		-----记录分隔符,每一行结束标记
-v		-----修改或创建awk变量,传递变量
&&		-----并且
^		-----以……开头的列
$		-----以……结尾的列
~		-----包含,匹配
BEGIN{}	----命令处理前执行
END{}	----命令处理后执行
ORS		-----输出记录分隔符(默认值是一个换行符)
OFS		-----修改输出字段分隔符(默认值是一个空格)
ARGV	-----包含命令参数的属组
FIELDWIDTHS	-字段宽度列表(用空格键隔开)
substr(s,i[,n])	-----把字符串s中的从i个字符开始级以后的n个字符截取

比较表达式:

格式
	运算符		含义		   示例 
<       小于          x<y 
<=      小于或等于     x<=y 
==      等于          x==y 
!=      不等于         x!=y
>=      大于等于        x>=y
>       大于          x>y

3.4.6 参数示例:

查询-取行

$0: 所有内容
NR:记录输出文件的编号(行号)
FNR`当前输入文件的编号(行号)

输出所有内容

//输出文件全部内容
[root@Shell ~]# awk '{print $0}' /etc/passwd

//输出文件全部内容并且加上每一行的行号
[root@Shell ~]# awk '{print NR,$0}' /etc/passwd

//将该文件前三行内容取出来
[root@Shell ~]# awk 'NR<=3' /etc/passwd

//一次输出两个文件的内容并且加上行号
[root@Shell ~]# awk '{print NR,$0}' /etc/passwd /etc/hosts

//一次输出两个文件的内容,给每个文件内容加上行号
[root@Shell ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts


取行

NR==n 取文件第N行内容
NR:显示输出文件编号

//取出文件第二行的内容
awk 'NR==2{print $0}'		(显示二2行的全部内容)

//取第一行到第三行的内容
[root@web01 for]# awk 'NR==1,NR==3{print $0}' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

//取第一行和第三行的内容
[root@web01 for]# awk 'NR==1;NR==3{print $0}' /etc/passwd

//取出以root开头的行
[root@Shell ~]# awk '/^root/' /etc/passwd

//取出以root开头的行
[root@Shell ~]# awk '$0 ~ /^root/' /etc/passwd

查询-取列

查找列内容

NF:文件的最后一列

//取出文件的第二列的内容
awk '{print $2}' /etc/hosts

//取出文件的最后一列内容
awk '{print $NF}' /etc/hosts

//取文件倒数第二列内容
awk '{print $(NF-1)}' /etc/hosts
		
//保存行的最后一列并输出列号
[root@Shell ~]# awk -F ":" '{print NF,$NF}' /etc/passwd /etc/hosts

统计文件列数

NF:统计文件列数
-F:创建分隔符,字段分隔符
[]:匹配[]中指定范围内的任意一个字符

//原文件内容
[root@Shell ~]# cat b.txt 
lzy lizhenya:is a:good boy!

//统计文件总列数
[root@Shell ~]# awk '{print NF}' b.txt
4

//以‘:’为分隔符,统计文件有多少列
[root@Shell ~]# awk -F ':' '{print NF}' b.txt
3

//以空格和冒号为分隔符,统计文件列数
[root@Shell ~]# awk -F"[ :]" '{print NF}' b.txt
6

查询匹配内容

//匹配字段:匹配操作符(~ !~)

~:传递数据,将前面的数据传递给
!~:不传递该数据

//查询文件第一列以root开头的列
[root@Shell ~]# awk '$1~/^root/' /etc/passwd
[root@Shell ~]# awk '$NF !~ /bash$/' /etc/passwd

范围-查找内容

格式:
awk ‘//,//’(从包含什么内容开始,到包含什么内容结束)

示例:
[root@li ~]# awk '/root/,/operator/' /etc/passwd

创建分隔符

-F:创建分隔符,字段分隔符
在awk里默认的分隔符为单个空格 连续空格 tab键
FS 创建分隔符,字段分隔符

//以冒号为分隔符,显示文件第二列的内容
[root@li ~]# awk -F':' '{print $2}' /etc/passwd

//以冒号为分隔符,取1~3行的第二列内容
[root@web01 for]# awk -F":" 'NR==1,NR==3{print $1}' /etc/passwd

//以冒号作为字段分隔符,查找包含root的行,并且取出第一列和第三列
[root@Shell ~]# awk -F: '/root/{print $1,$3}' /etc/passwd

//以冒号作为字段分隔符,查找包含root的行,并且取出第一列和第三列
[root@Shell ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd

//以空格冒号tab作为字段分割,取出第一二三列的内容
[root@Shell ~]# awk -F'[ :\t]' '{print $1,$2,$3}' /etc/passwd

OFS指定输出字段分隔符*

//,逗号映射为OFS, 初始情况下OFS变量是空格

//以冒号为分隔符,取出1 2 3 4列内容(观察每列之间是以空格隔开的)
[root@Shell ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd

//以冒号为分隔符,取出1 2 3 4列的内容,指定分隔符为+++ (观察每列之间的分隔符更换为了+++)
[root@Shell ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd
```

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093247288-1731343297.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093247542-889334199.png)

**awk使用变量**
> -v:修改或创建awk变量,传递变量
OFS:输出字段分隔符(默认值是一个空格)

**图片理解**
https://www.processon.com/view/link/5aa1df8ae4b0b089b9e60cbd

```
//调换 /etc/passwd第1列和最后一列的内容
[root@web01 oldboy]# awk -F: -vOFS=: '{a=$1;$1=$NF;$NF=a;print}' /etc/passwd
》使用-F指定冒号为分隔符,OFS将默认输出分隔符(空格)修改为冒号,-v创建awk变量,传递数据数据;将第一列赋值给a,将最后一列赋值给第一列,在将a赋值给最后一列,最后打印输出,完成调换。
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093247822-371130982.png)

## 3.4.6.1	比较表达式:
```
格式
	运算符		含义		   示例 
```
```
<       小于          x<y 
<=      小于或等于     x<=y 
==      等于          x==y 
!=      不等于         x!=y
>=      大于等于        x>=y
>       大于          x>y
```
**比较表达式示例**
```
//将uid为0的列出来
		[root@Shell ~]# awk -F ":" '$3==0' /etc/passwd
		
//将uid小于10的全部列出来
		[root@Shell ~]# awk -F: '$3 < 10' /etc/passwd
		
//用户登陆的shell等于/bin/bash
		[root@Shell ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd
		
//第一列为root的列出来
		[root@Shell ~]# awk -F: '$1 == "root" ' /etc/passwd 
		
//将为root的用户列出来
		[root@Shell ~]# awk -F: '$1 ~ /root/ ' /etc/passwd 

//将非root的用户列出来
		[root@Shell ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd
		
//磁盘使用率大于多少则,则打印可用的值
		[root@Shell ~]# df |awk '/\/$/'|awk '$3>1000000 {print $4}'
			\\解析:df:查看磁盘空间命令,awk '/\/$/' :查找以 / 结尾的行(根目录表示符号);awk '$3>1000000 {print $4}' 筛选第三列大于1000000的行,打印出第四列的内容。
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093248172-1322689222.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093248443-998486976.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093248748-929436279.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093249056-1239726437.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093249360-1177085524.png)


**数字对比**
```
		在比较数字的时候有时候会有出现错误,比如数字和字符挨着,系统就会把数字当做符号,现在就需要在“条件”后面加数字参数,目的就是告诉系统这是数字,或者就是指定新的分隔符
	示例:
		awk -F":" '$3>1000' /etc/passwd
		df -h | awk '$5+0>10'
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093249668-1951254760.png)

### 过滤

**正则表达式作为键(过滤)**
```
格式
	awk ‘//’ 文件路径  (//里面属于需要过滤的内容) 
```
**示例**
```
//查找文件中包含root的行
[root@web01 oldboy]# awk '/root/' /etc/passwd
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093249900-815856913.png)

### 条件表达式
```
格式:
	awk '$?>$?{print $0}' 文件路径 (根据条件筛选对应的条件)
```
```
//查找文件第三列大于300的行
[root@Shell ~]# awk -F: '$3>300 {print $0}' /etc/passwd
//查找文件第三列大于300的行
[root@Shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd

//查找文件中第三列大于555的内容,否则打印出第一列的内容。
[root@Shell ~]# awk -F: '{if($3>555){print $3} else {print $1}}' /etc/passwd
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093250184-1968025193.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093250555-284757100.png)

**运算表达式**
```
格式:
	awk '$? 运算符号 * ' 文件路径
```
```
加 +
减 -
乘 *
除  /
幂 **。例子:4**0.5=2.0
整除(地板除,向下取整) //。例子:5//2=2  -5//2=-3
取余 %。例子:5%2=1  -5%2=1  5%(-2)=-1  (-5)%(-2)=-1
```
```
//取文件第三列加上10的结果
[root@li ~]# awk -F: '{print $3+10}' /etc/passwd

//取文件第三列减去10的结果
[root@li ~]# awk -F: '{print $3-10}' /etc/passwd

//取文件第三列乘以10的结果
[root@Shell ~]# awk -F: '{print $3*10}' /etc/passwd

//打印出文件第三列乘以10,后结果小于50的列
[root@li ~]# awk -F: '($3*10<50) {print $3*10}' /etc/passwd

//取出文件第三列的内容,第三列的内容乘以10,如果大于500,则输出文件第1列和第三列,否则,输出“no”,在执行结束后输出“打印OK”字样。
[root@Shell ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>500) {print $1,$3} else {print "no"}  } END {print "打印ok"} ' /etc/passwd

//打印出包含admin的行的第三列加10的结果
[root@li ~]# awk -F: '/admin/{print $3+10}' /etc/passwd
1010
//打印出包含admin的行的第三列减去10的结果
[root@li ~]# awk -F: '/admin/{print $3-10}' /etc/passwd
990
//打印出包含admin的行的第三列乘以10的结果
[root@li ~]# awk -F: '/admin/{print $3*10}' /etc/passwd
10000
//打印出包含admin的行的第三列除以10的结果
[root@li ~]# awk -F: '/admin/{print $3/10}' /etc/passwd
100
//打印出包含admin的行的第三列取余的结果
[root@li ~]# awk -F: '/admin/{print $3%2}' /etc/passwd
0

```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093250904-2146798305.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093251198-1516598720.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093251463-320233692.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093251732-1259234660.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093252062-1679655067.png)

**逻辑操作符和复合模式***
```
&&	逻辑“与,并且”
||	逻辑“或,或者”
!	逻辑“非,不,取反” 

//匹配用户名为root并且打印uid小于15的行
[root@Shell ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd 

//匹配用户名为root或uid大于500
[root@Shell ~]# awk -F: '$1~/root/ || $3>=500' /etc/passwd

//匹配用户名不为root的行
awk '$1 !~/root/' /etc/passwd
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093252339-1886038175.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093252623-1951915350.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093252981-193931791.png)

### 替换
```
格式
	awk ‘{gsub(//,””);print $0}’   (//里面输入要替换的内容,””里面输入替换后的内容)
```
示例:
```
将00替换为11

[root@web01 oldboy]# awk '{gsub(/00/,"11");print $0}' 01.txt
17/Apr/2015:09:29:24 +0811
17/Apr/2015:09:30:26 +0811
17/Apr/2015:09:31:56 +0811
18/Apr/2015:09:34:12 +0811
```

### 特殊条件:	BEGIN{} 、END{}
```
含义:
BEGIN{}:
	BEGIN {}:里面的内容,会在awk读取文件之前执行,现在一般用于计算
	
END{}:
	END{}:里面的内容,会在awk读取文件之后执行,显示最终结果
```
**BEGIN{} 计算**
```
*	乘,乘以
**	次幂,次幂和次方的意义是一样的,只是中文叫法不一样
^	次方,次幂和次方的意义是一样的,只是中文叫法不一样
%	取余
```
```
格式:
	awk  ‘BEGIN{print 计算的内容}’
```
**示例:**
```
//计算3乘以2
[root@li ~]# awk 'BEGIN{print 3*2}'
[root@li ~]# awk 'BEGIN{print 3**2}'
[root@li ~]# awk 'BEGIN{print 3^2}'
[root@li ~]# awk 'BEGIN{print 3%2}'

//BEGIN在行处理前, 修改字段分隔符,将默认分隔符修改为':',并去除第一列内容
		[root@Shell ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd
		
//BEGIN在行处理前, 修改字段读入和输出分隔符
		[root@Shell ~]# awk 'BEGIN{FS=":";OFS="---"} {print $1,$2}' /etc/passwd
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093253314-372520878.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093253611-1759636514.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093253927-1293777455.png)



### 自动加法公式:
```
  	i=i+1	或 i++	(
		i就是变量),统计查询内容的次数/个
	i=i+$1	或i+=$??	求和
		都需要用print 加变量显示结果
```
**示例:**
```
#awk在执行过程中是一行一行的去读取文件的,每次开始前都会去读取一遍命令,i就会去运算,从而完成统计
	i=i+1   使用END{} 输出
//源文件
[root@web01 oldboy]# cat 01.txt
17/Apr/2015:09:29:24 +0800
17/Apr/2015:09:30:26 +0800
17/Apr/2015:09:31:56 +0800

//统计文件的列数,
[root@web01 oldboy]# awk '{i=i+1}END{print i}' 01.txt	#直接显示最后结果
[root@li ~]#  awk '{i=i+1;print i}' 01.txt	#显示执行结果

//统计17出现的次数
[root@li ~]# awk '/17/{i++;print i}' 01.txt	#显示执行过程

[root@li ~]# awk '/17/{i++}END{print i}' 01.txt	#直接显示执行结果

```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093254186-1607614569.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093254437-2112185511.png)

**i=$i+$??		求和运算**

```
//使用脚本计算1..100所有数的和的结果
#!/bin/bash
for i in {1..100}
do
	let sum=$sum+$i
done
echo $sum
[root@web01 oldboy]# sh w.sh
5050
```

**`print`格式化输出函数***
```
//以现在是“..年..月..号-时间”的格式,格式化时间
[root@li ~]# date | awk '{print "现在是"$NF"年"$1"月"$3"号""-"$4}'

//以“用户是.. 用户UID:用户GID:”的格式输出
[root@li ~]# awk -F: '{print "用户是:"$1 "\t 用户UID:"$3 "\t 用户GID:"$4}' /etc/passwd
```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093254774-663497420.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093255103-1539581069.png)

**printf 函数,式样化输出函数**
```
参数:
	%s 字符类型
	%d 数值类型
	- 表示左对齐,默认是右对齐
		#printf 默认不会在行尾自动换行,加\n
```
```
//于echo命令的输出,Linux是经管道发给awk。printf函数包含一个控制串。百分号让printf做好准备,它要打印一个占15个格、向左对齐的字符串,这个字符串夹在两个竖杠之间,并且以换行符结尾。百分号后的短划线表示左对齐。控制串后面跟了一个逗号和$1。printf将根据控制串中的格式说明来格式化字符串Linux。
[root@li ~]# echo "Linux" | awk '{printf "|%-8s|\n",$1}' 
|Linux   |
//字符串Linux被打印成一个占8格、向右对齐的字符串,夹在两个竖杠之间,以
换行符结尾。
[root@li ~]# echo "Linux" | awk '{printf "|%8s|\n",$1}' 
|   Linux|

```
![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093255389-327786209.png)

![](/i/l/?n=23&i=blog/2052744/202406/2052744-20240617093255702-1043125213.png)

**FIELDWIDTHS 字段宽度列表(用空格键分隔)**
```
[root@shells ~]# echo 20190101 |awk -vFIELDWIDTHS="4 2 2" -vOFS=- '{print $1,$2,$3}' 
2019-01-01
```
## 3.5 awk数组
	处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)
**文件内容:**
```
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
```
**答案**
```
[root@shells ~]# awk -F"[/.]+"   '{h[$2]=h[$2]+1}END{print h["www"],h["mp3"],h["post"]}' url.txt
3 1 2
[root@shells ~]# awk -F"[/.]+"   '{h[$2]=h[$2]+1}END{for(i in h) print i}' url.txt
www
mp3
post
[root@shells ~]# awk -F"[/.]+"   '{h[$2]=h[$2]+1}END{for(i in h) print i,h[i]}' url.txt
www 3
mp3 1
post 2
```
**统计access.log中每个ip地址出现次数**
```
[root@shells ~]# awk   '{h[$1]++}END{for(i in h) print i,h[i]}' access.log  |sort -rnk2 |head 
58.220.223.62 12049
112.64.171.98 10856
114.83.184.139 1982
117.136.66.10 1662
115.29.245.13 1318
223.104.5.197 961
116.216.0.60 957
180.111.48.14 939
223.104.5.202 871
223.104.4.139 869
实时统计
[root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}'
```
**3.5.1 统计access.log中每个状态码出现次数**
```
[root@shells ~]# awk   '{h[$9]++}END{for(i in h) print i,h[i]}' access.log  |sort -rnk2 |head 
200 142666
304 18712
404 3863
302 789
499 418
400 242
301 146
413 50
403 37
408 13
```
**3.5.2 统计每个ip地址使用的总流量**
```
[root@shells ~]# awk   '{h[$1]=h[$1]+$10}END{for(i in h) print i,h[i]}' access.log  |sort -rnk2 |head 
114.83.184.139 31362956
117.136.66.10 22431302
116.216.30.47 21466000
223.104.5.197 21464856
116.216.0.60 19145329
114.141.164.180 17219553
114.111.166.22 17121524
223.104.5.202 16911512
116.228.21.187 15969887
112.64.171.98 15255013
```
**3.5.3 awk脚本**
```
#!/bin/awk

#awk   '{h[$1]=h[$1]+$10}END{for(i in h) print i,h[i]}' access.log
{
   h[$1]=h[$1]+$10
}
END{
for(i in h) 
   print i,h[i]
}
[root@shells ~]# awk -f ip.awk access.log
```
## 3.5.4 awk函数

	注意事项
		awk  '//'
		#awk '$NF~/bash/' /etc/passwd  #最后一列中包含bash 
		#awk '/bash/' /etc/passwd      #这一行中只要有bash就行  
		#awk '$0~/bash/' /etc/passwd   #这一行中只要有bash就行    

**awk 只有条件的时候,默认的动作**
```
awk '/bash/{print $0}' /etc/passwd  
```
**3.5.5 企业面试题:请过滤range.log中在device: {}里面出现了多少次oldboy,过滤并统计出来**
**环境:**
```
oldboy is a linuxer.
device: {
oo
oldboy
no sql
this is log
niu niu
}
oldboy
device: {
oldboy
no sql
this is log
niu niu
}
oldboy
device: {
oldboy
no sql
this is log
niu niu
}
device: {
oldboy
no sql
this is log
niu niu
}
```
**答案:**
```
[root@web01 oldboy]# awk '/{/,/}/' 1.txt|grep -c 'oldboy'
4
 [root@web01 oldboy]# awk '/{/,/}/{if(/oldboy/)i++}END{print i}' 1.txt
4
```
**3.5.6 统计2018年01月25日,当天的PV量***
```
[root@Shell ~]# grep "25/Jan/2018" log.bjstack.log |wc -l
[root@Shell ~]# awk "/25\/Jan\/2018/" log.bjstack.log |wc -l	
[root@Shell ~]# awk '/25\/Jan\/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' log.bjstack.log

//统计15-19点的pv量
[root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00 {print $0}"' log.bjstack.log |wc -l
```

**3.5.7 统计日志中每分钟每个ip地址访问次数**
**原文:日志的第一行内容**
```
[root@web01 ~]# head -1 access.log 
101.226.61.184 - - [22/Nov/2015:11:02:00 +0800] "GET /mobile/sea-modules/gallery/zepto/1.1.3/zepto.js HTTP/1.1" 200 24662 "http://m.oldboyedu.com.cn/mobile/theme/ppj/home/index.html" "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; HUAWEI CRR-UL00 Build/HUAWEICRR-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025478 Mobile Safari/533.1 MicroMessenger/6.3.7.5
```
**答案:**
```
方法一:
[root@web01 ~]# awk -F'[[/: ]' '{a[$1" "$4"/"$5"/"$6":"$7":"$8":"$9]++}END{for (i in a) print i,a[i]}' access.log |sort -rnk3|head
112.64.171.98 /22/Nov:2015:11:20 570
58.220.223.62 /22/Nov:2015:11:56 433
58.220.223.62 /22/Nov:2015:11:42 426
112.64.171.98 /22/Nov:2015:11:19 426
112.64.171.98 /22/Nov:2015:11:18 402
112.64.171.98 /22/Nov:2015:11:40 395
112.64.171.98 /22/Nov:2015:11:05 392
58.220.223.62 /22/Nov:2015:11:08 373
58.220.223.62 /22/Nov:2015:11:47 333
112.64.171.98 /22/Nov:2015:11:09 321

方法二:	substr	
[root@web01 files]# awk '{t=substr($4,2,17);h[$1" "t]++}END{for (i in h)print i,h[i]}' access.log |sort -rnk3|head 
112.64.171.98 22/Nov/2015:11:20 570
58.220.223.62 22/Nov/2015:11:56 433
58.220.223.62 22/Nov/2015:11:42 426
112.64.171.98 22/Nov/2015:11:19 426
112.64.171.98 22/Nov/2015:11:18 402
112.64.171.98 22/Nov/2015:11:40 395
112.64.171.98 22/Nov/2015:11:05 392
58.220.223.62 22/Nov/2015:11:08 373
58.220.223.62 22/Nov/2015:11:47 333
112.64.171.98 22/Nov/2015:11:09 321
思路:将ip地址和时间通过分隔符看做一个整体,通过(i++)加数组进行匹配,最后通过for循环,sort 将某个时间段及ip出现频率最高的进行输出
```
**3.5.8 日志中每个用户被破解了多少次**
```
[root@web01 files]# awk '/Failed password/{h[$(NF-5)]++}END{for (i in h) print i,h[i]}' secure-20161219 |sort -rnk2|head 
root 364610
admin 725
user 245
oracle 119
support 104
guest 79
test 70
ubnt 47
pi 41
webadmin 36
```
**3.5.9 那个IP地址破解的用户登录的次数最多**
```
[root@web01 files]# awk '/Failed password/{h[$(NF-3)]++}END{for (i in h) print i,h[i]}' secure-20161219 |sort -rnk2|head 
218.65.30.25 68652
218.65.30.53 34326
218.87.109.154 21201
112.85.42.103 18065
112.85.42.99 17164
218.87.109.151 17163
218.87.109.150 17163
218.65.30.61 17163
218.65.30.126 17163
218.65.30.124 17163
```
**3.5.10 统计日志中,每个ip访问的次数和每个ip使用的流量总数;优先按照ip出现的次数排序,然后根据流量大小进行排序**
```
[root@web01 files]# awk '{ip[$1]++;li[$1]+=$10}END{for (i in ip )print i,ip[i],li[i]/1024^2}' access.log |sort -rnk2 -k3|head
																	
58.220.223.62 12049 12.0192
112.64.171.98 10856 14.5483
114.83.184.139 1982 29.91
117.136.66.10 1662 21.3922
115.29.245.13 1318 1.10766
223.104.5.197 961 20.4705
116.216.0.60 957 18.2584
180.111.48.14 939 12.9787
223.104.5.202 871 16.1281
223.104.4.139 869 8.0237
原理:awk的运算的时候都调用了$1这个变量行,所以执行的时候,两个数组都会一起执行,到输出的时候书写任一数组,另外一数组也会被赋值进来
```

**3.5.11 统计系统中管理用户,普通用户,虚拟用户的个数**
```
[root@web01 ~]# cat /etc/passwd|awk -F: '{if($3==0){i++}else if($3+0>=1000){a++}else if($3>0 && $3<1000){j++}}END{print "管理员用户有"i"个","普通用户有"a"个","虚拟用户有"j"个"}'
管理员用户有1个 普通用户有29个 虚拟用户有25个
```
**统计2018年01月25日,访问状态码为404及出现的次数($status)***
```
 [root@Shell ~]# grep "404" log.bjstack.log |wc -l
[root@Shell ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
```
**统计2018年01月25日,8:30-9:00访问状态码是404***
```
 [root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
[root@Shell ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
```
**统计2018年01月25日,各种状态码数量***
```
//统计状态码出现的次数
[root@Shell ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
[root@Shell ~]# awk '{if($9>=100 && $9<200) {i++}
else if ($9>=200 && $9<300) {j++}
else if ($9>=300 && $9<400) {k++}
else if ($9>=400 && $9<500) {n++}
else if($9>=500) {p++}}
END{print i,j,k,n,p,i+j+k+n+p}' log.bjstack.log
```

标签:2052744,passwd,etc,awk,Linux,print,root
From: https://www.cnblogs.com/megshuai/p/18248229

相关文章

  • 深入理解Linux内核中的同步与互斥的实现
    1.内联汇编汇编函数的执行效率比C语言更高,但可移植性,可编程性和可读性更差,掌握也更复杂。所以一般使用C语言编程。1.1内联汇编的优点性能优化:内联汇编允许开发者利用底层硬件特性,编写出更高效的代码,尤其是在性能敏感的场景下。直接硬件控制:内联汇编可以直接对硬件寄存......
  • 如何对Linux系统进行基准测试3工具Geekbench
    Geekbench简介Geekbench是一款跨平台的处理器、内存等基准测试程序,可用于评估各种设备(包括智能手机、平板电脑、笔记本电脑和台式电脑)的性能。它通过运行一系列模拟真实使用场景的工作负载来衡量设备的CPU、内存和计算能力。Geekbench提供单核和多核评分,以及综合评分。Geekben......
  • linux内核中的HZ
    在Linux内核中,HZ 是一个非常重要的宏定义,它代表了内核的“心跳”频率,即每秒内核时钟中断的次数。这个值在不同的系统和架构上可能有所不同,但通常是一个固定的值,比如100、250或1000等,这取决于硬件的能力和内核的配置。3*HZ 顾名思义,就是 HZ 值的三倍。这个表达式在内核代码......
  • 每天学一个 Linux 命令(16):mkdir
    命令简介mkdir命令用于创建新目录。创建目录时,如果目录名前没有指定路径,那么就直接在当前工作目录下创建新的目录。如指定了路径,那么就会在这个指定的目录下创建一个新目录。创建目录是需要注意,你所创建的目录名与当前目录下的文件名没有重名,如果有重名,系统会出现如下的提示,无......
  • linux命令
    centos7的命令1.目录切换命令语法:cd[切换的目录]切换到上一级目录:cd../切换到根目录:cd/2.查看目录下的内容ls[参数][目录]参数:-a所有隐藏的列出-l列表3.查看当前所在的目录。4.创建文件命令touch创建文件>5.创建目录命令......
  • linux配置时间同步
    1、配置 systemctlstatuschronyd  //查看同步服务状态yum-yinstallchrony //如果没有服务就装包systemctlstartchronyd //开启服务systemctlenablechronyd //设置开机自启vim/etc/chrony.conf //修改配置文件server172.25.0.254iburst //......
  • Linux 重定向
    前言    在LINUX系统中,往往一个命令只实现简单的操作,例如ls、cat、head、tail等等。复杂的操作,一般情况下是简单命令的作用。这得益于Linux的重定向与管道功能,能够将一些列简单的指令组合来完成复杂的操作。另外,重定向与管道能够应用的一个基础是LINUX中的处理绝大数......
  • Linux系统搭建轻量级个人博客VanBlog并一键发布公网远程访问
    文章目录前言1.Linux本地部署2.VanBlog简单使用3.安装内网穿透4.创建公网地址5.创建固定公网地址前言今天和大家分享如何在LinuxUbuntu系统搭建一款轻量级个人博客VanBlog,并结合cpolar内网穿透软件生成公网地址,轻松实现随时随地远程访问本地部署的站点。无需......
  • linux高级编程(sqlite数据库调用)
    数据库1、分类:大型  中型        小型      ORACLE MYSQL/MSSQL SQLITE DBIIpowdb      关系型数据库    2、名词:      DB      数据库selectupdatedatabase      DBMS   数据库管理......
  • 内存管理-19-vmlinux.lds.S分析
    基于msm-5.4一、简介链接器主要任务是将符号引用解析到符号定义上,将多个目标文件(.o)和库文件合并成为一个可执行文件或者动态链接库,生成符号表,并对程序代码做最后的检查和优化。这个链接脚本在Linux内核里就是vmlinux.lds.S文件。vmlinux.lds.S编译后会在out/target目录......