shell awk 常用命令

网友投稿 263 2022-09-04

shell awk 常用命令

在”a b c d”的b后面插入3个字段e f g

echo a b c d|awk '{$3="e f g "$3}1'

获取ipv4地址:

方法一:

ifconfig | awk '/inet / && !($2 ~/^127/){print $2}'

方法二:

ifconfig | awk 'BEGIN{RS=""} !/^lo/{print $6}'

方法三:

ifconfig | awk 'BEGIN{RS="";FS="\n"}!/lo/{$0=$2;FS=" ";$0=$0;print $2;FS="\n"}'

读取ini中mysql 的配置文件:

[base]name=os_repobaseurl== = 1gpgcheck = 0

#/\[mysql\]/awk 'index($0,"[mysql]"){ print while ( (getline var) >0){ if(var ~ /\[.*\]/){ exit } print var }}' 1.txt #getline返回值:#>0:表示读取到数据#=0:表示遇到结尾EOF,没有读取到东西#<0: 表示读取报错#按段读awk 'BEGIN{RS=""} /\[mysql\]/{ print; while((getline)>0){ if(/\[.*\]/){ exit } print } }' 1.txt

去除重复的数据:

awk -F "?" '{arr[$2]=arr[$2]+1;if(arr[$2]==1){print}}' 1.txt awk -F "?" '{arr[$2]++;if(arr[$2]==1){print}}' 1.txt awk -F "?" '!arr[$2]++' 1.txt awk -F "?" '!arr[$2]++{print}' 1.txt

2019-01-13_12:00_index?uid=1232019-01-13_13:00_index?uid=1232019-01-13_14:00_index?uid=3332019-01-13_15:00_index?uid=97102019-01-14_12:00_index?uid=1232019-01-14_13:00_index?uid=1232019-01-15_14:00_index?uid=3332019-01-16_15:00_index?uid=9710

awk 次数统计

portmapperportmapperportmapperportmapperportmapperportmapperstatusstatusmountdmountdmountdmountdmountdmountdnfsnfsnfs_aclnfsnfsnfs_aclnlockmgrnlockmgrnlockmgrnlockmgrnlockmgr

awk '{arr[$0]++}END{for(i in arr){print arr[i],i}}' 1.txtawk '{arr[$0]++}END{OFS="\t";for(idx in arr){print arr[idx],idx}}' 1.txt

获取tcp连接: netstat -tnap

awk 统计TCP连接状态数量:

netstat -tnp | awk '/^tcp/{arr[$6]++}END{for(i in arr){print arr[i],i}}'

netstat -tnap | awk '/^tcp/{arr[$6]++}END{for(state in arr){print arr[state] ": " state}}'

netstat -tnap 2>/dev/null | awk '/^tcp/{arr[$6]++}END{for(state in arr){print arr[state] ": " state}}'

netstat -tna | /usr/bin/grep 'tcp' | awk '{print $6}' | sort | uniq -c

统计日志中ip访问非200状态码的次数:

awk '$8!=200{arr[$1]++}END{PROCINFO["sorted_in"]="@val_num_desc";for(i in arr){if(cnt++==10){exit}print arr[i],i}}' access.log

awk '$8!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10

awk 统计独立Ip

url访问ip反问时间反问人

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guestb.com.cn|202.109.134.23|2015-11-20 20:34:48|guestc.com.cn|202.109.134.24|2015-11-20 20:34:48|guesta.com.cn|202.109.134.23|2015-11-20 20:34:43|guesta.com.cn|202.109.134.24|2015-11-20 20:34:43|guestb.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

BEGIN{ FS="|"}{if(!arr[$1,$2]++){ arr1[$1]++}}END{ for(i in arr1){ print i,arr1[i] >(i".txt") }}

BEGIN{ FS="|"}!arr[$1,$2]++{ arr1[$1]++}END{ for(i in arr1){ print i,arr1[i] >(i".txt") }}

执行:

awk -f 1.awk 1.txt

awk处理字段缺失的数据:

ID name gender age email phone1 Bob male 28 abc@qq.com 180233940122 Alice female 24 def@gmail.com 180849252033 Tony male 21 170487925034 Kevin male 21 bbb@189.com 170239290335 Alex male 18 ccc@xyz.com 181859042306 Andy female ddd@139.com 189239023527 Jerry female 25 exdsa@189.com 187852349068 Peter male 20 bax@qq.com 177293487589 Steven 23 bc@sohu.com 1594789321210 Bruce female 27 bcbd@139.com 13942943905

gawk为了解决这种特殊需求,提供了FIELDWIDTHS变量。

awk '{print $4}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt

BEGIN{ FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11"}{ print $0}

awk 处理字段中包含了字段分隔符的数据

Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

需求:取得第三个字段”1234 A Pretty Street, NE”

FPAT可以收集正则匹配的结果,并将它们保存在各个字段中。(就像grep匹配成功的部分会加颜色显示,而使用FPAT划分字段,则是将匹配成功的部分保存在字段$1 $2 $3...中)。

echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'

方法2:

BEGIN{ FPAT="[^,]+|\".*\""}{ print $1,$3}

awk -f 1.awk 1.txt

awk 取字段中指定字符数量

16 001agdcdafasd16 002agdcxxxxxx23 001adfadfahoh23 001fsdadggggg

awk '{print $1,substr($2,1,3)}' 1.txt

awk '{print $1,$2}' FIELDWIDTH="2 2:3" 1.txtawk 'BEGIN{FIELDWIDTH="2 2:3"}{print $1,$2}' 1.txt

awk 行转列

name agealice 21ryan 30

{ for(i=1;i<=NF;i++){ if(i in arr){ arr[i]=arr[i]" "$i }else{ arr[i]=$i } }}END{ for(i=1;i<=NF;i++){ print arr[i] }}

awk 筛选给定是时间范围内的日志

grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现

但是awk提供了mktime()函数,它可以将时间转换成epoch时间值

# 2019-11-10 03:42:40转换成epoch$ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'1573328560

可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小

strptime1()实现的是将2019-11-10T03:42:40+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志

BEGIN{ str="2019-11-10T20:25:39+08:00" #strptime(str) 筛选什么时间的日志,将其构建成epoch 值 which_time=mktime("2019 11 10 03 42 40")}{ #去除日志中的日期时间字符串部分 match($0,"^.*\\[(.*)\\].*",arr) #将日期时间字符串转换成eposh值 tmp_time=strptime(arr[1]) #通过比较epoch值来比较时间 if(tmp_time>which_time){ print }}function strptime (str ,arr,Y,M,D,H,m,S){ patsplit(str,arr,"[0-9]{1,4}") Y=arr[1] M=arr[2] D=arr[3] H=arr[4] m=arr[5] S=arr[6] return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))}

strptime2()实现的是将10/Nov/2019:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

BEGIN{ # 要筛选什么时间的日志,将其时间构建成epoch值 which_time = mktime("2019 11 10 03 42 40")}{ # 取出日志中的日期时间字符串部分 match($0,"^.*\\[(.*)\\].*",arr) # 将日期时间字符串转换为epoch值 tmp_time = strptime2(arr[1]) # 通过比较epoch值来比较时间大小 if(tmp_time > which_time){ print }}# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"function strptime2(str ,dt_str,arr,Y,M,D,H,m,S) { dt_str = gensub("[/:+]"," ","g",str) # dt_sr = "10 Nov 2019 23 53 44 08 00" split(dt_str,arr," ") Y=arr[3] M=mon_map(arr[2]) D=arr[1] H=arr[4] m=arr[5] S=arr[6] return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))}function mon_map(str ,mons){ mons["Jan"]=1 mons["Feb"]=2 mons["Mar"]=3 mons["Apr"]=4 mons["May"]=5 mons["Jun"]=6 mons["Jul"]=7 mons["Aug"]=8 mons["Sep"]=9 mons["Oct"]=10 mons["Nov"]=11 mons["Dec"]=12 return mons[str]}

awk去除/**/之间的内容

文档:

/*AAAAAAAAAA*/1111222/*aaaaaaaaa*/323231234123412134 /*bbbbbbbbbb*/ 13241214534122/* cccccccccc*/xxxxxx /*ddddddddddd cccccccccc eeeeeee*/ yyyyyyyy5642341

两种实现方式:

/\/\*/{ #同行有*/ if(/\*\//){ print gensub("(.*)/\\*.*\\*/(.*)","\\1\\2","g",$0) }else{ #同行没有“*/” # 1.去掉/*行后面的内容 print gensub("(.*)/\\*.*","\\1","g",$0) #2.继续读取,直到出现*/,并去掉中间的所有数据 while((getline)>0){ if(/\*\//){ print gensub(".*\\*/(.*)","\\1","g",$0) } } }}#非注释内容!/\/\*/{print}index($0,"/*"){ #如果*/在同行 if(index($0,"*/")){ print gensub("^(.*)/\\*.*\\*/(.*)$","\\1\\2","g",$0) }else{ #*/不同行 #输出/*前面的内容 print gensub("^(.*)/\\*.*","\\1","g",$0) #继续读取,直到遇到*/结束符 while((getline var)>0){ if(index(var,"*/")){ print gensub("^.*\\*/(.*)","\\1","g",var) break } } } }!index($0,"/*"){ print}

从如下类型的文件中,找出false段的前一段为i-order的段,同时输出这两段

2019-09-12 07:16:27 [-][ 'data' => [ ' ],]2019-09-12 07:16:27 [-][ 'data' => [ false, ],]2019-09-21 07:16:27 [-][ 'data' => [ ' ],]2019-09-21 07:16:27 [-][ 'data' => [ ' ],]2019-09-17 18:34:37 [-][ 'data' => [ false, ],]

方法1:

BEGIN{ RS="]\n" ORS=RS}{ if($0 ~ /false/ && prev ~ /i-order/){ print prev print $0 } prev=$0}

grep -Pz '(?s)\d+((?!2019).)*i-order(?1)+\d+(?1)+false(?1)+'

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:同程旅游以创新营销推出“预约未来旅行”!
下一篇:shell获取网口和ip,选择网口Ip列表
相关文章

 发表评论

暂时没有评论,来抢沙发吧~