awk常用方法

awk内建变量

1
2
3
4
5
6
7
8
9
10
$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列 ,$(NF-n)为倒数第n个字段
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

BEGIN EDN语法

  • BEGIN{ 这里面放的是执行前的语句 }
  • {这里面放的是处理每一行时要执行的语句}
  • END {这里面放的是处理完所有的行后要执行的语句 }
    示例如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #运行前
    BEGIN {
    math = 0
    english = 0
    computer = 0
    printf"NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"    printf"---------------------------------------------\n"
    }
    #运行中
    {
    math+=$3
    english+=$4
    computer+=$5
    printf"%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
    }
    #运行后
    END {
    printf"---------------------------------------------\n"
    printf"  TOTAL:%10d %8d %8d \n", math, english, computer
    printf"AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
    }

常用功能

求和

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

求平均

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

求最大值

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

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

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

求访问次数的Top 10 Resource,可以根据此进行优化

cat output/logs/cookie_logs/date +%u/cookie_log|grep -v '172.16'|grep -v '127.0.0.1' |awk -F' ' '{ if(index($1,"219.141.246")!=0) print $2; else print $1 } '|sort|uniq -c|sort -n |tail -n 10

求最大最小值

cat 1.log | awk 'BEGIN {max=0; min=1000} {sum +=$9; num +=1; if($9>max) max=$9 fi; if($9<min) min=$9 fi;} END {print "avg=",sum/num, "\nmax=",max, "\nmin=", min}'

awk中执行shell命令

1
2
3
4
5
6
7
8
9
10
11
12
13
awk '{cmd="rm "$0;system(cmd)}' filename ----OK
下面的也ok
awk '{cmd="rm "$0;cmd|getline }' filename ---- OK
man awk里面关于getline的说明,大意是说 运行command,同时会把输出存在$0 里面,或参数var中。

command | getline [var]
Run command piping the output either into $0 or var, as above.
command |& getline [var]
Run command as a co-process piping the output either into $0 or var, as above.
Co-processes are a gawk extension.
ps -ef |grep CipRouter | grep -v "grep" | awk -F' ' '{cmd="ls /proc/"$2"/fd/ | wc -l ";system(cmd); }'|awk '{num+=$1} END {print "sum= ",num}'
或者
ps -ef |grep CipRouter | grep -v "grep" | awk -F' ' '{cmd="ls /proc/"$2"/fd/ | wc -l ";cmd|getline; sum+=$0;} END {print sum}'

awk 多个进程号转为数组

aaa=(ps -ef |grep xxx |grep -v grep |awk ‘{print $2}’) echo "${aaa[@]}"

awk -F 特殊字符

,\"dn\":\"baiducdnct.inter.iqiyi.com\" 以"dn\":\来分割,因为\为特殊字符,所以需要转义,每4个\为一个过滤\ awk -F'dn\\\\":\\\\' '{print $2}'

awk 打印从某一列到最后一列的内容

awk -F " " '{for (i=2;i<=NF;i++)printf("%s ", $i);print ""}'

清理除第一行和最后一行的的bash进程

1
2
3
# awk 命令将第一行和最后一行给去掉了, NR>2{}{} 的理解为当前行大于2时打印p的当前值并将当前行的$2赋值给p, 否则只将当前行的$2给p  , 不能使用$p
# xargs -r 其中-r参数为当xargs 参数为空是不执行任何命令
ps -ef --sort start_time |grep bash |grep -v "grep" |awk 'NR>2{printf p" "}{p=$2}' |xargs -r kill -9

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!