awk详解

本文详细介绍了awk命令,包括其概念、使用格式、内置与自定义变量、print和printf的区别与用法、break、continue和next的控制语句、常用函数、awk脚本的编写以及常见应用实例,帮助读者深入理解和掌握awk在文本处理中的强大功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

二、使用格式

1.命令行方式
awk [-F  field-separator]  'commands'  input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk

3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

三、变量

变量分为内置变量和自定义变量,但只要是变量都是用的选项-v

先选常用的内置变量说明下,然后说下自定义的变量。
1、内置变量:

FS:输入字段分隔符,默认为空白字符,这个想当于-F选项。分隔符可以是多个,用[]括起来表示,如:-v FS="[,./-:;]"
OFS:输出字段分隔符,默认为空白字符,分隔符可以是多个,同上
RS :输入记录(所认为的行)分隔符,指定输入时的换行符,原换行符仍有效,分隔符可以是多个,同上
ORS :输出记录(所认为的行)分隔符,输出时用指定符号代替换行符,分隔符可以是多个,同上
NF:字段数量
NR:记录数(所认为的行)
FNR :各文件分别计数, 记录数(行号)
FILENAME :当前文件名
ARGC:命令行参数的个数
ARGV :数组,保存的是命令行所给定的各参数

2、自定义变量(区分字符大小写):

在'{...}'前,需要用-v var=value:awk -v var=value '{...}'
在program 中直接定义:awk '{var=vlue}'

下面针对每个变量都举个例子:

awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
awk –F: '{print $1,$3,$7}’ /etc/passwd
awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
awk -v RS=' ' ‘{print }’ /etc/passwd
awk -v RS="[[:space:]/=]" '{print }' /etc/fstab |sort
awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
awk -F: ‘{print NF}’ /etc/fstab, 引用内置变量不用$
awk -F: '{print $(NF-1)}' /etc/passwd
awk '{print NR}' /etc/fstab ; awk 'END{print NR}' /etc/fstab
awk '{print FNR}' /etc/fstab /etc/inittab
awk '{print FNR}' /etc/fstab /etc/inittab
awk '{print FILENAME}’ /etc/fstab
awk '{print ARGC}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGV[0]}’ /etc/fstab   /etc/inittab
awk ‘BEGIN {print ARGV[1]}’ /etc/fstab  /etc/inittab
awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello,gawk";print test}'
awk –F:‘{sex=“male”;print $1,sex,age;age=18}’ /etc/passwd
awk -F: '{sex="male";age=18;print $1,sex,age}' /etc/passwd
echo "{print script,\$1,\$2}"  > awkscript
awk -F: -f awkscript script=“awk” /etc/passwd

四、awk的print和printf

print和printf都是打印输出的,不过两者用法和显示上有些不同而已。

print 格式:print item1,item2, ...
printf格式:printf “FORMAT ”,item1,item2, ...

要点
1.逗号为分隔符时,显示的是空格;
2.分隔符分隔的字段(域)标记称为域标识,用$0,$1,$2,...,$n表示,其中$0 为所有域,$1就是表示第一个字段(域),以此类推;
3.输出的各item可以字符串,也可以是数值,当前记录的字段,变量或awk 的表达式等;
4.如果省略了item ,相当于print $0
5.对于printf来说,必须指定FORMAT,即必须指出后面每个itemsN的输出格式,且还不会自动换行,需要显式则指明换行控制符"\n"

printf的格式符和修饰符

%c:显示字符的ASCII码
%d, %i:显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%:显示%自身
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
-:左对齐(默认右对齐);%-15s,就是以左对齐方式显示15个字符长度
+:显示数值的正负符号 %+d

这里也举个示例:

awk '{print "hello,awk"}'
awk –F: '{print}' /etc/passwd
awk –F: ‘{print “wang”}’ /etc/passwd
awk –F: ‘{print $1}’ /etc/passwd
awk –F: ‘{print $0}’ /etc/passwd
awk –F: ‘{print $1”\t”$3}’ /etc/passwd
tail –3 /etc/fstab |awk ‘{print $2,$4}’
awk -F: ‘{printf "%s",$1}’ /etc/passwd
awk -F: ‘{printf "%s\n",$1}’ /etc/passwd
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F: ‘{printf "Username: %s\n",$1}’ /etc/passwd
awk -F: ‘{printf “Username: %s,UID:%d\n",$1,$3}’ /etc/passwd
awk -F: ‘{printf "Username: %15s,UID:%d\n",$1,$3}’ /etc/passwd
awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}’ /etc/passwd
lsmod
awk -v FS=" " 'BEGIN{printf "%s %26s %10s\n","Module","Size","Used by"}{printf "%-20s %13d %5s %s\n",$1,$2,$3,$4}' /proc/modules

五、awk的break、continue和next

break 和continue,用于条件判断循环语句,next是用于awk自身循环的语句。

break[n]:当第n次循环到来后,结束整个循环,n=0就是指本次循环
continue[n]:满足条件后,直接进行第n次循环,本次循环不在进行,n=0也就是提前结束本次循环而直接进入下一轮
next:提前结束对本行的处理动作而直接进入下一行处理

示例:

awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}‘
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}‘
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

六、AWK的函数

awk的函数有许多,除了系统自带的内建函数还有就是用户自定义的函数,这里挑选几个常用的函数。

rand():返回0 和1 之间一个随机数
srand():生成随机数种子
int():取整数
length([s]):返回指定字符串的长度
sub(r,s,[t]):对t字符串进行搜索,r表示的模式匹配的内容,并将第一个匹配的内容替换为s
gsub(r,s,[t]):对t字符串进行搜索,r表示的模式匹配的内容,并全部替换为s所表示的内容
split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array 所表示的数组中,第一个索引值为1, 第二个索引值为2,…也就是说awk的数组下标是从1开始编号的。
substr(s,i,[n]):从s所表示的字符串中取子串,取法:从i表示的位置开始,取n个字符。
systime():取当前系统时间,结果形式为时间戳。
system():调用shell中的命令。空格是awk中的字符串连接符,如果system 中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用"" 引用 起来。

自定义函数,格式为

function fname ( arg1,arg2 , ... ) {
statements
return expr
}

自定义函数中fname为函数名,arg1...为函数的参数,statements是动作语言,return expr为由statements的结果从而决定最终函数所显示的内容。
示例:

cat fun.awk
    function max(v1,v2) {
        v1>v2?var=v1:var=v2
        return var
    }
      BEGIN{a=3;b=2;print max(a,b)}
awk –f fun.awk

七、awk的脚本

awk的脚本就是将awk程序写成脚本形式,来直接调用或直接执行。例如上面写自定义函数的样子也算是脚本。

格式1:
BEGIN{} pattern{} END{}
格式2:
\#!/bin/awk  -f
\#add 'x'  right 
BEGIN{} pattern{} END{}

格式1假设为f1.awk文件,格式2假设为f2.awk文件,那么用法是:

awk [-v var=value] f1.awk [file]
f2.awk [-v var=value] [var1=value1] [file]

对于awk [-v var=value] f1.awk [file]来说,很好理解,就是把处理阶段放到一个文件而已,真正展开后,也就是普通的awk语句。
对于f2.awk [-v var=value] [var1=value1] [file]来说, [-v var=value]是在BEGIN之前设置的变量值,[var1=value1]是在BEGIN过程之后进行的,也就是说直到首行输入完成后,这个变量才可用,这就想awk脚本黄总传递参数了。
示例:

cat f1.awk
    {if($3>=1000)print $1,$3}
awk -F: -f f1.awk /etc/passwd

cat f2.awk
    #!/bin/awk –f
    #this is a awk script
    {if($3>=1000)print $1,$3}
    #chmod +x f2.awk
f2.awk –F: /etc/passwd

cat test.awk
    #!/bin/awk –f
    {if($3 >=min && $3<=max)print $1,$3}
    #chmod +x test.awk
test.awk -F: min=100 max=200 /etc/passwd

八、awk常见小题

1、统计输出结果的最后一列之和:
result | awk -F'\t' -v sum=0 '{sum += $NF} END{print sum}'

2、统计文件 t1.log 中最后一列中大于 5 的那些域的和,并将其输出:

awk -v sum=0 '{if($NF>5) sum+=$NF} END{print sum}'

3、求和

cat data|awk '{sum+=$1} END {print "Sum = ", sum}'

4、求平均

cat data|awk '{sum+=$1} END {print "Average = ", sum/NR}'

5、求最大值

cat data|awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'

4、求最小值(min的初始值设置一个超大数即可)

awk 'BEGIN {min = 1999999} {if ($1<min) min=$1 fi} END {print "Min=", min}'

九、更多

https://linuxtools-rst.readthedocs.io/zh_CN/latest/base/03_text_processing.html#id14

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值