awk太过庞大,过滤打印、浮点运算、条件判断,这里只是整理了一下自己的笔记。
语法:
awk [option] 'program' var=value《file》
awk [option] -f programfile var=value《file》
其中program通常被单引号,并可以有3部分组成
- BEGIN语句块(对文件处理前执行,表头)
- 模式匹配通用语句块
- END语句块(对文件处理后执行,做结果统计)
常见选项:
- -F 指定分隔符(支持正则表达式)
- -v var=value 变量复制
注:awk中字符串必须要用双引号!默认空格为分隔符。
例:
#指定多个分隔符:以空格、:、%为分隔符(支持正则表达式)
awk -F " +|:|%"
#定义变量并引用(注-v也可以引用外部变量)
awk -v AAA=123 'BEGIN{print AAA}'
awk -F: -v AAA="===" '{print $1 AAA $3 }' /etc/passwd
awk -F: -v AAA="===" -v BBB="---" '{print $1 AAA $3 BBB}' /etc/passwd
#引用外部变量hostname,打印主机名
awk -v AAA=$HOSTNAME 'BEGIN{print "主机名:" AAA}'
###################打印:print###################
###以/etc/passwd文件为例
#打印指定列
#打印第1,3列(获取用户名和用户ID)
awk -F: '{print $1,$3}' /etc/passwd
#打印字符串(字符串需要双引号)
awk 'BEGIN{print "《打印的内容》"}'
########指定列######
###打印指定列大于或小于指定值的行(硬盘使用率使用较多!)
例:
#cat disk.txt
devtmpfs 486M 0 486M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 748K 495M 1% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/vda1 20G 2.3G 17G 13% /
/dev/vda1 20G 10G 10G 50% /home
#只打印run和home行
cat disk.txt|awk '/run/;/home/ {print}'
#打印硬盘使用率大于20%的行,且只打印后两列(结果值为:50% /home)
#df -h |tr -d "%"|awk '$5>20{print $(NF-1) " " $NF}'
###不打印指定列,其他列正常打印(其实也就将指定列为空)
例:排除第2、3列
#cat test.log
2021-11-03 nginx test1 post /admin.php
2021-11-03 15:30:30 tomcat get /wp-index.php
#cat test.log|awk '{$2=$3="";print}'
###################输出分隔符:OFS###################
###使用OFS参数定义输出分隔符,默认”,“ 代表空格分隔符
#使用OFS定义定义输出分隔符为”-“
awk -F: -v OFS='-' '{print $1,$3,$6}' /etc/passwd
###当然,如果不使用OFS定义,也可以使用字符串进行分割(但当输出的列较多是就比较费力)
#输出以字符串”-“和”_“为分隔符(字符串必须用双引号)
awk -F: '{print $1"-"$3"_"$6}' /etc/passwd
#输出以tab为分隔符:\t
awk -F: '{print $1"\t"$3}' /etc/passwd
#输出以换行为分隔符:\n
awk -F: '{print $1"\n"$3}' /etc/passwd
##################输入记录的换行符:RS##################
##默认以换行符进行划分行,可以通过RS去定义新的换行符
如下:
cat test.txt
a,b,c;1,2
3,4;x,y,z;aaa,b
bb,ccc
#使用”,“为分隔符,使用”;“为换行符
awk -F, -v RS=';' '{print $2}' test.txt
b
2
3
y
b
bb
##################输出的换行符:ORS#################
#定义输出的换行符(默认是回车换行,可以自定义换行)
#获取用户名以|替换换行符合
awk -F: -v ORS="|" '{print $1}' /etc/passwd
###################列标:NF(number field)###################
#打印列数NF
awk -F: '{print NF}' /etc/passwd
#打印最后一列$NF(NF列标记,$最后)
awk -F: '{print $NF}' /etc/passwd
#打印倒数第二列$(NF-1)
awk -F: '{print $(NF-1)}' /etc/passwd
##################行标:NR(number record)##################
#仅打印列标
awk '{print NR}' /etc/passwd
#打印列标及内容($0代表全部)
awk '{print NR,$0}' /etc/passwd
#打印指定行:第3行(NR==为真)
awk 'NR==3' /etc/passwd
#打印指定行:第1~3和5行
awk 'NR>=1&&NR<=3;NR==5' /etc/passwd
###########过滤(双斜线):/ 《过滤内容》/ ###########
#过滤包含root的行
awk '/root/' /etc/passwd
#过滤以root开头的行
awk '/^root/' /etc/passwd
#过滤root用户,并打印第1、3行(获取用户名、用户id)
awk -F: '/^root/{print $1,$3}' /etc/passwd
###################运算###################
#awk支持浮点运算(awk单独运算需加入BEGIN)
awk 'BEGIN {print 10/3}'
#awk中print支持外界变量,引用外部变量需加$和单引号(printf不支持变量)
AAA=100
BBB=33
awk 'BEGIN {print ('$AAA'-'$BBB')/'$AAA'}'
#awk列求和(BEGIN标记初始SUM=0)
awk -F "《分隔符》" 'BEGIN{SUM=0}{SUM=SUM+$《列标》}END{print SUM}' 《文件》
###printf格式化输出
格式符:(格式符需要“”双引号引起了)
%c:显示字符的ASCI吗
%d,%i:显示十进制整数
%e,%E:显示科学计数法数值
%f:显示为浮点数
%g,%G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号数
%%:显示%自身
修饰符
#[.#]第一个数字控制显示的完度;第二个表示小数点后精度,如:%3.1f(整数3位,小数点一位)
- 左对齐(默认右对齐)如:%-15s (字符宽度15,靠左对齐)
+ 显示数值的正负符号如:%+d
#$1为字符串用%s,设置长度为20个,$2为整数使用%d,长度10(多个变量需要多个%)
awk -F: '{printf "%20s:%10d\n", $1,$3}' /etc/passwd
#$1和最后一列$NF都是字符串,所以都用%s,且都定义左对齐
awk -F: '{printf "%-20s:%-15s\n", $1,$NF}' /etc/passwd
#运算
#保留2位小数(%.2f)
awk 'BEGIN {printf"%.2f",10/3}'
#不保留小数(%.0f)
awk 'BEGIN {printf"%.0f",10/3}'
#printf不支持变量,但可以管道输入
AAA=100
BBB=33
echo "$AAA $BBB" |awk '{printf "%.2f",$1/$2}'
################BEGIN和END################
#BEGIN,表头输出=====,
#第一个{}BEGIN读入文件之前执行,第二个{}文件操作,第三个{}END文件结束之后
#仅打印BEGIN
awk 'BEGIN{print "======";print "BEGIN内容"}'
#打印BEGIN和文件内容
awk 'BEGIN{print "======";print "BEGIN内容"}{print}' /etc/passwd
#打印BEGIN+文件内容+END
awk 'BEGIN{print "======";print "BEGIN内容"}{print}END{print"------"}' /etc/passwd
发表评论