awk基础

一、awk结构

awk -F '分割符' 'BEGIN{可选} /执行条件/{主体} END{可选}' filepath

注:多个文件时,读取从左到右,读完第一个再读取第二个

执行条件(pattern)可以是如下:

1:/正则表达式/:使用通配符的扩展集;

2:关系表达式: 可以是字符串或数字的比较,如$2>$1选择第二个字段比第一个字段长的行;

3:模式匹配表达式:~ 匹配; ~!不配置。

1、程序结构

BEGIN 块(初始化变量、关键字、可选)

BEGIN {awk-commands}

在BEGIN块被在程序启动时执行,且只执行一次。这是一个很好的初始化变量的地方。 BEGIN是AWK关键字,因此它必须是大写,可选的。

Body块

/pattern/ {awk-commands}

主体块适用于AWK的每个输入行命令。默认情况下AWK执行每一行命令,但可以通过提供的模式限制。请注意,没有主体块的关键字,必选。

END 块

END {awk-commands}

END块被在程序结束时执行,END是AWK关键字,因此它必须是大写。请注意,此块也是可选的。

示例

让创建一个包含序列号的学生,名字,科目并标记成绩,文件的名称为:marks.txt。

1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89

现在用AWK脚本显示包含头文件的内容。

awk 'BEGIN{printf "Xuhao \tName\tKemu\tMarks\n"} {print}' marks.txt

当执行上面的代码时,会产生以下结果

Xuhao 	Name	Kemu	Marks
1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89

在程序启动时AWK从BEGIN块,打印头部文字。然后,在主体块时,它从一个文件读取一行,并执行打印标准输出流的内容,使用AWK的printf命令。这个过程不断重复,直到文件被耗尽。

2、流程

读取

AWK从输入流(文件,管道,或标准输入)读取一行,并将其存储在存储器(内存)中。

执行

所有的AWK命令依次提交输入。默认情况下AWK执行命令每一行,但我们可以通过提供的模式限制。

重复

重复这个过程,直到该文件被处理完成。

二、使用事例

awk -F '|' '$2>3 {print $1}' data.cvs	//打印指定字段 {print $1} 序号1开始

指定分隔符 -F '|' (可多个分隔符)
awk -F '|' '$2>3 {print $1}'	
awk -F 'ms' '{print $1}'     //可使用字符串分割(不可多个字符串)
awk -F"[@ /t]" '{print $2,$3}' test		//以@,空格,Tab键分割test文件的每一行,并输出第二、第三列。(不可多字符串)

//只展示匹配的行
$ awk '$4 ~/Technology/'	//只第4个字段匹配的行 (不匹配 ~!)
$ awk '$1 ~/^root/' test	//将显示test文件第一列中以root开头的行。

//调用外部shell
ls -l |awk '$1~/^d/{system("du -s "$9)}'	//筛选出当前目录下的左右文件夹并显示大小。

//过滤出两个文件中相同行
awk -F'[/,]' 'NR==FNR{a[$1]=$1}NR>FNR{if ($2 in a) print $0}' b a >c		//推荐,先将记录放在数组中!

//求平均值/求和
awk '{sum+=$1} END {print "Average = ", sum/NR}'

//删除特定文件外的所有其它文件
rm -rf `ls -lrt|awk '{if(match($0,".bes.cm.")) print $9}' |awk '{if( !(match($0,"bes.cm.base.meta.object-") || match($0,"bes.cm.base.meta.sdk-") || match($0,".bes.cm.base.sdk-") )) print $0}'`

* / % || && > >= == !=

三、awk内置函数(split/substr/length)和 复合表达式

1、split 初始化和类型强制

awk的内建函数split允许你把一个字符串分隔为单词并存储在数组中。你可以自己定义域分隔符或者使用现在FS(域分隔符)的值。
格式:

split (string, array, field separator)
split (string, array) -->如果第三个参数没有提供,awk就默认使用当前FS值。

例子

#t="12:34:56"

#echo $t | awk '{split($0,a,":");print a[1],a[2],a[3]}'
12 34 56

统计一月份工资

cat saryly.txt
vivi     2013-01-18  400
Tom    2013-01-20  300
zjz    2013-01-28  500
zjz    2013-01-29  500
zjz    2013-02-28  500
John   2013-01-28  300
John   2013-01-29  500
John   2013-02-28  500
John   2013-01-30  100

awk '{split($2,a,"-");if(a[2]==01){b[$1]+=$3}} END{for(i in b)print i,b[i]}' saryly.txt | sort -nrk2 |column -t

统计人名出现的次数

cat saryly.txt
vivi       400
Tom      300
zjz      500
zjz      500
zjz      500
John     300
John     500
John     500
John     100

cat saryly.txt   |  awk   '{name[$1]++} END{for(i in name) print i,name[i]}' | column -t |sort  -rnk2
John     4
zjz      3
vivi      1
Tom      1

#echo $t
12:34:56

#echo $t | awk '{split($0,a,":" ); for (i=1; i<=3; i++) print a[i]}'
12
34
56

2、substr 截取字符串

格式:
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分

#echo "1 2 3 张小明 zaijian" | awk  '{print substr($5,3,3)}'
iji

#echo "1 2 3 张小明 zaijian" | awk  '{print substr($5,3)}'
ijian

3、length 字符串长度

length函数返回没有参数的字符串的长度。length函数返回整个记录中的字符数。

#echo "123zjz多少遍" | awk '{print length}'
9

如何使用 awk 复合表达式

https://blog.csdn.net/Listen2You/article/details/73864630

cat  netstat.txt | awk /LISTEN/
tcp        0 0 0.0.0.0:3306           0.0.0.0:* LISTEN
tcp        1 1 0.0.0.0:80             0.0.0.0:* LISTEN
tcp        0 0 127.0.0.1:9000         0.0.0.0:* LISTEN
tcp        0 0 :::22                  :::* LISTEN

awk使用&&复合表达式

awk '$1 =="tcp" && $2 > 0' netstat.txt
tcp        1 1 0.0.0.0:80             0.0.0.0:* LISTEN

# awk 'NR==1 || $1 =="tcp" && $2 > 0' netstat.txt
oecv-Q Send-Q Local-Address          Foreign-Address             State
tcp        1 1 0.0.0.0:80             0.0.0.0:* LISTEN

awk实现用户活跃时间段统计
zcat  com.log20160529.gz | grep ‘dianping_reply’ |  awk '{split($4,array,"[");if(array[2]>="29/May/2016:00:00:26" && array[2]<="29/May/2016:00:01:14"){print $0}}’

解释
扫描gz压缩文件,从中寻找带有`dianping_reply`的行,将改行按照`[`进行拆分,然后直接使用if条件进行判断,比较,最终输出想要的结果。
zcat 直接读取压缩文件的内容
grep用来过滤特定字符的行
split用来切分字符串
shell命令处理两个文件中的相同部分

行中部分列对应相同。file1.txt的第二列与file2.txt的第一列对应相等。表格的第三列为待输出内容

如果使用grep遇到了内存耗尽的问题,可尝试这个方法:

awk 'NR==FNR{a[$1]}NR>FNR && ($1 in a){print $1}' a.txt b.txt > match.txt

!!注意:如果a文件太大也可能存在内存耗尽的问题,这个时候尝试把文件a,b的位置互换。

awk 'NR==FNR{a[$1]}NR>FNR && ($1 in a){print $1}' b.txt a.txt > match.txt 

https://blog.csdn.net/hzhj2007/article/details/106713238/

字段意义
NR已经读出的记录数,就是行号,从1开始
FNR各文件分别计数的行号
NR==FNR表示读第一个文件时的条件分支。  因为行数相等
NR>FNR表示读第二个文件时的条件分支
a存储数据的字典型变量,所以字段值应该保持唯一,否则会被覆盖;
$0当前行的所有内容
$1当前行的第一列
a[$1]=$0以第一列作为key值,存储当前行的内容$0
next忽略之后的语句,进行下一行的匹配

范围查找磁盘空间

$ df -h |awk -F '[ %]+' '{if(NR!=1 && $5 >= 65) print}'
/dev/sda3                       47G   32G   16G   67% /
10.1.1.2:/mnt/data/nfs/public   66T   65T  1.3T   99% /mnt/nfs

打印时间范围的日志

awk '/^# Time: 130912/ {slow=($NF>"10:09:00" && $NF<"10:11:00")}slow' slow.log

awk 'BEGIN{RS="# Time: 130912"}$1>"10:09:00"&&$1<"10:11:00"{print RS,$0}'

用awk数组去除重复域  awk ‘!a[$1]++’

指定某一列,当再次出现相同数值时,舍弃。

# cat  test.txt 
1 2 3
1 2 2
2 2 2
3 4 4
3 4 5
2 2 2
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
1 4 3

#  awk '!a[$1]++' test.txt 
1 2 3
2 2 2
3 4 4
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8

#  awk '!a[$2]++' test.txt 
1 2 3
3 4 4
5 5 5
6 6 6
7 7 7
8 8 8

https://www.yiibai.com/awk   易百awk教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少安在线锤人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值