awk基本用法
概述
awk的主要功能是对文本进行数据提取、转换和报告。它使用一种类似于编程语言的语法,可以通过编写脚本或在命令行中指定参数来使用。awk脚本由一系列的规则组成,每个规则由一个模式和一个动作组成。模式用于匹配输入行,动作用于对匹配的行执行操作。
基本用法格式
awk的基本用法格式
-
awk [options] ‘program’ FILE…
- 语句之间用分号分隔
-
[options]
-
-F
: 指明输入时用到的字段分隔符 -
-v var=VALUE
: 自定义变量
- 在awk中变量的引用不需要加
$
,而是直接引用
- 在awk中变量的引用不需要加
-
我们可以吧awk分为三个模式组成,处理输入前的任务,处理输入过程中将做的处理,处理输入完成后做的处理。
print所出现的内容与选取的的文本本身无关,所输出的内容可以根据你所选取的内容进行变更
[root@localhost ~]# echo "hello" | awk '{print "nihao"}'
nihao
[root@localhost ~]# cat llao
456
asrsae
zxcvz
Why are you so skilled?
pure "oxygen"
asd
[root@localhost ~]# awk '/^$/ {print "This is blank line"}' llao
This is blank line
This is blank line
上面的文本有两处空行,就打印了两次
选择分隔符
FS
: input field seperator,输入的分隔符,默认为空白字符
OFS
: output field seperator,输出的分隔符,默认为空白字符
//以:为分隔符,输出第一列和第六列内容
[root@localhost ~]# head /etc/passwd |awk 'BEGIN {FS=":"}{print $1,$6}'
root /root
bin /bin
daemon /sbin
adm /var/adm
lp /var/spool/lpd
sync /sbin
shutdown /sbin
halt /sbin
mail /var/spool/mail
operator /root
//输出时选择-为分隔符
[root@localhost ~]# head /etc/passwd |awk 'BEGIN {FS=":";OFS="-"}{print $1,$6}'
root-/root
bin-/bin
daemon-/sbin
adm-/var/adm
lp-/var/spool/lpd
sync-/sbin
shutdown-/sbin
halt-/sbin
mail-/var/spool/mail
operator-/root
赋值
赋值方法和shell脚本里的赋值方法差不多,引用变量的时候可以直接引用
[root@localhost ~]# echo "" |awk 'BEGIN {f=1+5}{print f}'
6
我们在主任务开始前定义了f的值为1+5也就是6
我们后面可以直接使用f这个变量不需要和shell脚本里一样要用到$符
[root@localhost ~]# head /etc/passwd |awk 'BEGIN {FS=":";OFS="-";f=1+5}{print $1,$f}'
root-/root
bin-/bin
daemon-/sbin
adm-/var/adm
lp-/var/spool/lpd
sync-/sbin
shutdown-/sbin
halt-/sbin
mail-/var/spool/mail
operator-/root
统计空行
[root@localhost ~]# cat llao
456
asrsae
zxcvz
Why are you so skilled?
pure "oxygen"
asd
[root@localhost ~]# awk '/^$/{print x+=1}' llao
1
2
[root@localhost ~]# awk '/^$/{x+=1}END{print x}' llao
2
计算平均值
[root@localhost ~]# cat asd
lc 80 91 92 89 82
lxy 82 90 95 85 86
zmq 90 89 81 82 93
[root@localhost ~]# awk '{c=$2+$3+$4+$5+$6;avg=c/5;print $1,avg}' asd
lc 86.8
lxy 87.6
zmq 87
多行进行运算
[root@localhost ~]# cat ppp
1000
125 Market -125.45
126 Hardware Store -34.95
127 Video Store -7.45
128 Book Store -14.32
129 Gasoline -16.10
[root@localhost ~]# cat ppp|awk 'NR==1{print "Beginning Balance: " $1;niub=$1;next}{print $1,$2,$3,$4;print niub+=$3}'
Beginning Balance: 1000
125 Market -125.45
874.55
126 Hardware Store -34.95
874.55
127 Video Store -7.45
874.55
128 Book Store -14.32
874.55
129 Gasoline -16.10
858.45
处理多行文本
- NR:当前行号(Number of Records)。NR变量表示当前处理的行号,从1开始计数。例如,可以使用
NR==5
来匹配第5行。 - NF:当前行的字段数(Number of Fields)。NF变量表示当前行的字段数,可以通过
NF==3
来匹配有3个字段的行。 - 0:当前行的完整内容。0:当前行的完整内容。0变量表示当前行的完整内容,可以通过
$0
来引用当前行。 - 1,1,2, 3,…:当前行的字段值。3,…:当前行的字段值。1, 2,2,3等变量表示当前行的第1、2、3等字段的值。例如,可以使用
$2=="abc"
来匹配第2个字段等于"abc"的行。 - FS:字段分隔符(Field Separator)。FS变量表示字段的分隔符,默认是空格或制表符。可以通过
FS=","
来指定逗号作为字段分隔符。 - RS:记录分隔符(Record Separator)。RS变量表示记录的分隔符,默认是换行符。可以通过
RS="@"
来指定"@"作为记录分隔符。 - OFS:输出字段分隔符(Output Field Separator)。OFS变量表示输出时字段的分隔符,默认是空格。可以通过
OFS=","
来指定逗号作为输出字段分隔符。 - ORS:输出记录分隔符(Output Record Separator)。ORS变量表示输出时记录的分隔符,默认是换行符。可以通过
ORS="@"
来指定"@"作为输出记录分隔符。
[root@localhost ~]# ll -h| awk 'BEGIN{print "BYTES","\t","FILE"}NR!=1{OFS="\t ";print $5,$9;}'
BYTES FILE
1.4K anaconda-ks.cfg
56 asd
736 cai.sh
90 lamp
61 llao
3.0K lxy-lamp.tar.xz
获取文件信息,并添加标题
[root@localhost ~]# ll | awk 'BEGIN{print "BYTES","\t","FILE"}NR!=1{OFS="\t ";print $5,$9;sum += $5;++filenum}END{print "Total: ",sum,"bytes (" filenum "files)"}'
BYTES FILE
1340 anaconda-ks.cfg
56 asd
736 cai.sh
90 lamp
61 llao
3036 lxy-lamp.tar.xz
Total: 5319 bytes (6files)
格式化打印
在awk中,可以使用printf
函数来进行格式化打印。printf
函数的语法与C语言中的printf
函数类似,可以使用格式化字符串来指定输出的格式。
printf
函数的基本语法如下:
printf format-string, expr1, expr2, ...
其中,format-string
是格式化字符串,用于指定输出的格式。expr1
、expr2
等是要输出的表达式,可以是常量、变量、算术表达式等。
格式化字符串中可以包含普通字符和格式控制符。格式控制符以百分号(%)开头,后面跟着一个或多个字符,用于指定输出的格式。以下是一些常用的格式控制符:
- %d:输出十进制整数。
- %f:输出浮点数。
- %s:输出字符串。
- %c:输出字符。
- %x:输出十六进制整数。
- %o:输出八进制整数。
- %%:输出百分号。
除了格式控制符,格式化字符串中还可以包含其他普通字符。例如,可以使用"Hello, %s!\n"
来输出带有字符串的消息。
示例
[root@localhost ~]# echo "" |awk '{printf "|%s|\n","hello"}'
|hello|
[root@localhost ~]# echo "" |awk '{printf "|%10s|\n","hello"}'
| hello|
//%10s代表此字符串少于10个字符时用空格在左边填充,%-10s则是在右边填充
[root@localhost ~]# echo "" |awk '{printf "|%-10s|\n","hello"}'
|hello |
可以更改之前的命令
[root@localhost ~]# ll | awk 'BEGIN{print "BYTES","\t\t ","FILE"}NR!=1{printf("%-15s\t%10d\n",$9,$5);sum += $5;++filenum}END{printf("Total: %d bytes (%d files)\n",sum,filenum)}'
BYTES FILE
anaconda-ks.cfg 1340
asd 56
cai.sh 736
lamp 90
llao 61
lxy-lamp.tar.xz 3036
Total: 5319 bytes (6 files)