AWK

Posted 正在迷途

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AWK相关的知识,希望对你有一定的参考价值。

一、工作原理:

逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个""字段"然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符"&&"表示""与"、"||"表示"或"、"!"表示"非",还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

二、格式:

awk 选项 模式或条件 操作 文件 1 文件 2...

awk -f 脚本文件 文件 1 文件 2 ...

三、awk常用的内建变量(可直接使用):

  • FS:列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
  • NF:当前处理的行的字段个数。
  • NR:当前处理的行的行号(序数)。
  • $0:当前处理的行的整行内容。
  • $n:当前处理行的第n个字段(第n列)。
  • FILENAME:被处理的文件名。
  • RS:行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录, 而awk一次仅读入一条记录,以进行处理。预设值是 \\n

四、示例:

1.按行输出文本

awk print shuzi                        输出所有内容
awk print $0 shuzi 输出所有内容
awk NR==1,NR==3print shuzi 输出1到3行内容
awk (NR>=1)&&(NR<=3)print shuzi 输出1到3行内容
awk NR==1||NR==3print shuzi 输出第1行、第3行内容
awk (NR%2)==1print shuzi 输出所有奇数行的内容
awk (NR%2)==0print shuzi 输出所有偶数行的内容
awk /^root/print /etc/passwd 输出以root开头的行
awk /nologin$/print /etc/passwd 输出以nologin结尾的行
awk BEGIN x=0;/\\/bin\\/bash$/x++;END print x /etc/passwd 统计以/bin/bash结尾的行数,等同于grep -c "/bin/bash$" /etc/passwd

AWK_字段

AWK_字段_02

AWK_分隔符_03

AWK_分隔符_04

AWK_bash_05

AWK_bash_06

BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作,只执行1次后 awk再处理指定的文本,之后再执行END模式中指定的动作,END语句块中,往往会放入打印结果等语句

2.按字段输出文本:

awk -F ":" print $3 /etc/passwd               输出每行中(以空格或制表位分隔)的第3个字段
awk -F ":" print $1,$3 /etc/passwd 输出每行中的第1个和第3个字段
awk -F ":" $3<5print $1,$3 /etc/passwd 输出第3个字段的值小于5的行第1个和第3个字段
awk -F ":" !($3<200)print /etc/passwd 输出第3个字段的值不小于200的行
awk BEGIN FS=":";if($3>=1000)print /etc/passwd 先处理BEGIN的内容,在答应文本里面的内容
awk -F ":" max=($3>=$4)?$3:$4;print max /etc/passwd
($3>=$4)?$3:$4;三元运算符,如果第三个字段的值大于第四个字段的值,则把第三个字段的值赋给max,否则第四个字段的值赋给max
awk -F ":" print NR,$0 /etc/passwd 输出每行内容和行号,没处理完一条记录,NR值加1
awk -F ":" $7~"/bash"print $1 /etc/passwd 输出以冒号分隔且第7个字段中包含/bash的行的第1个字段
awk -F ":" ($1~"root")&&(NF==7)print $1,$2 /etc/passwd 输出第1个字段包含root且有7个字段的行的第1,2个字段
awk -F ":" ($7!="/bin/bash")&&($7!="/sbin/nologin")print /etc/passwd
输出第7个字段既不为/bin/bash,也不为/sbin/nologin的所有行

AWK_分隔符_07

AWK_字段_08

AWK_bash_09

AWK_分隔符_10

AWK_分隔符_11

AWK_字段_12

AWK_分隔符_13

AWK_分隔符_14

3.通过管道、双引号调用Shell命令

echo $PATH | awk BEGINRS=":";ENDprint NR          统计以冒号分隔的文件段落数
awk -F: /bash$/print | "wc -l" /etc/passwd 调用 wc -l 命令统计使用bash的用户个数。等同于grep -c "bash$" /etc/passwd
free -m | awk /Mem:/ print int($3/($3+$4)*100)"%" 查看当前内存使用百分比
top -b -n 1 | grep Cpu | awk -F , print $4 | awk print $1 查看当前CPU空闲率 -b -n 1 表示只需要一次的输出结果)
date -d "$(awk -F "." print $1 /proc/uptime) second ago" +"%F %H:$M:%S"
显示上一次系统重启的时间,等同于uptime;second ago为显示多少秒前的时间,+"%F %H:%M:%S"等同于+"%Y-%m-%d %H:%M:%S"的时间格式
awk BEGIN n=0 ; while ("w" | getline) n++ ; print n-2 调用w命令,用来统计在线用户
awk BEGIN "hostname" | getline ; print $0 调用hostname,输出当前的主机名
seq 10 | awk getline; print $0 获取偶数行
seq 10 | awk print $0; getline 获取奇数行

AWK_字段_15

AWK_字段_16

date -d "$(date -d"1 month" +"%Y%m01") -3 day" +"%Y%m%d" 当月的倒数第三天

date +"%Y%m01"  当月第一天

AWK_字段_17

AWK_分隔符_18

AWK_分隔符_19

AWK_分隔符_20

当getline左右无重定向符"<"或"|"时,awk首先读取到了第一行,就是1,然后getline,进入下一行读取1下面的第二行,就是2,因为setline之后,awk会改变对应的NF,NR,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。

当getline左右有重定向符"<"或"I"时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getlina读入,那么getline返回的是该文件的第一行,而不是隔行。


五、补充

FNR:awk当前读取的记录数,其变量值小于等于NR(比如当读取第二个文件时,FNR是从0开始重新计数,而NR不会)。

NR==FNR:用于在读取两个或两个以上的文件时,判断是不是在读取第一个文件

echo "A B C D" l awk OFS="/ " ; print $0;$1=$1;print $o

AWK_分隔符_21

以上是关于AWK的主要内容,如果未能解决你的问题,请参考以下文章

awk

在awk代码中引用shell变量的方法

精通awk系列:awk读取行的细节

awk 脚本帮助 - 逻辑问题

linux awk命令的使用

sh 使用awk删除可执行代码的有效负载