awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输(stdin)、一个或多个文件,或其它命令的输出。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
Linux awk 命令
工作中遇到一个需求,需要从nginx日志中获取调用方上游IP,需要对nginx日志进行处理,所以学习一下linux命令。
原理
语法
awk [options] 'scripts' var=value filename
常用参数
-F 指定分隔符(可以是字符串或正则表达式)
-f 从脚本文件中读取awk命令
-v var=value 赋值变量,将外部变量传递给awk
脚本基本结构
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' filename
一个awk脚本通常由BEGIN语句+模式匹配+END语句三部分组成,这三部分都是可选项.
工作原理:
- 第一步执行BEGIN 语句
- 第二步从文件或标准输入读取一行,然后再执行pattern语句,逐行扫描文件到文件全部被读取
- 第三步执行END语句
实例展示
echo "hello " | awk 'BEGIN{ print "welcome" } END{ print "2017-08-08" }'
welcome
2017-08-08
echo -e "hello" | awk 'BEGIN{ print "welcome" } {print} END{ print "2017-08-08" }'
welcome
hello
2017-08-08
#不加print参数时默认只打印当前的行
echo|awk '{ a="hello"; b="nihao"; c="mingongge"; print a,b,c; }'
hello nihao mingongge
#使用print以逗号分隔时,打印则是以空格分界
echo|awk '{ a="mgg"; b="mingg"; c="mingongge"; print a" is "b" or "c; }'
mgg is mingg or mingongge
#awk的print语句中双引号其实就是个拼接作用
echo -e "OK! \n" # -e 开启转义
内置变量
$0 #当前记录
$1~$n #当前记录的第N个字段
FS #输入字段分隔符(-F相同作用)默认空格
RS #输入记录分割符,默认换行符
NF #字段个数就是列
NR #记录数,就是行号,默认从1开始
OFS #输出字段分隔符,默认空格
ORS #输出记录分割符,默认换行符
外部变量
[root@localhost ~]# a=7
[root@localhost ~]# b=b
[root@localhost ~]# b=6
[root@localhost ~]# echo |awk '{print v1*v2 }' v1=$a v2=$b
42
AWK实例
以:为分隔符打印第二列
work@user-center-api-v1-85689f869-6htbw:/mnt/logs/nginx$ awk -F":" '{print $2}' /etc/passwd
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
以:分隔打印以work开头行的第三列内容
work@user-center-api-v1-85689f869-6htbw:/mnt/logs/nginx$ awk -F : '/^work/{print $3}' /etc/passwd
1000
以:分隔打印以r或者w开头行的第一列内容
work@user-center-api-v1-85689f869-6htbw:/mnt/logs/nginx$ awk -F : '/^[rw]/{print $1}' /etc/passwd
root
www-data
work
rd
获取nginx日志中的IP地址
日志格式如下:
remote_addr=[127.0.0.6] http_x_forward=[172.26.0.131,172.26.0.2] time=[2022-02-06T23:40:01+08:00] request=[POST
grep "/api/v2/userinfo/get_usernames" access-2022-02-06.log | awk -F" " '{print $2}'| awk -F "[][]" '{print $2}'| awk -F"," '{print $1"\n"$2}' | sort -r | uniq -c | more
204 172.26.0.3
228 172.26.0.2
432 172.26.0.131
匹配所有包含root的行
work@user-center-api-v1-85689f869-6htbw:/mnt/logs/nginx$ awk '/root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
以分号作为分隔符,匹配第5个字段是root的行
awk -F: '$5~/root/{print $0}' passwd
引用