linux三剑客之awk

awk工作模式

  awk是一个文本处理工具,通常用于处理数据并生成结果报告,按行处理

  

  语法格式

    第一种形式:awk 'BEGIN{}pattern{commands}END{}' filename

    第二种形式:standard out | awk 'BEGIN{}pattern{commands}END{}'

    第三种形式:awk -f scripts.awk filename

      将处理的命令写到文件中,然后指定这个文件执行awk

语法格式

解释

BEGIN{}

正式处理数据之前执行(读取第一行处理之前)

pattern

匹配模式(不写默认对所有行进行处理)

{commands}

处理匹配到内容的命令

END{}

处理完所有匹配数据后执行(最后一行处理完毕之后)

 

awk内置变量

  

内置变量

含义

$0

整行内容

$1-$n

当前行的第1-n个字段

NF(Number Field)

当前行的字段个数,也就是有多少列

NR(Number Row)

当前行的行号,从1开始计数

FNR(File Number Row)

多文件处理时,每个文件行号单独计数,都是从1开始(NR多个文件的情况下,是累加计数,第二个文件不会从1开始计数,而是接着第一个文件的数值开始累加计数)

FS(Field Separator)

输入字段分隔符(输入给awk命令处理)。不指定默认以空格或tab键分割

RS(Row Separator)

输入行分隔符。默认回车换行

OFS(Output Field Separator)

输出字段分隔符(awk命令处理完毕输出)。默认空格

ORS(Output Row Separator)

输出行分隔符。默认回车换行

FILENAME

当前处理的文件名称

ARGC

命令行参数个数

ARGV

命令行参数数组

# 输出/etc/passwd文件的全部内容

[root@VM_0_13_centos ~]# awk '{print $0}' /etc/passwd

# 输出/etc/passwd中的用户名,每一行以:为分隔符的第一个字段

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{print $1}' /etc/passwd

# 输出/etc/passwd中每一行字段的个数,每一行以:为分隔符

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{print NF}' /etc/passwd 

7

# 输出/etc/passwd中每一行的行号(从1开始)

[root@VM_0_13_centos ~]# awk '{print NR}' /etc/passwd             

1

2

3

4

#输出test.txt文件和/etc/passwd中每一行的行号(使用NR两个文件的行号没有单独计数,而是累加)(使用FNR两个文件的行号是单独计数,都从1开始)

[root@VM_0_13_centos ~]# awk '{print NR}' /etc/passwd test.txt

1

2

3

4

5

6

7

8

9

[root@VM_0_13_centos ~]# awk '{print FNR}' test.txt /etc/passwd

1

2

3

4

5

1

2

3

# 输入分隔符(FS、RS)

[root@VM_0_13_centos ~]# cat list.txt

Hadoop|Spark|Flume--JAVA|Python|Scala|Go--Allen|Mike|XYZ

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--"}{print $0}' list.txt   

Hadoop|Spark|Flume

JAVA|Python|Scala|Go

Allen|Mike|XYZ

 

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--";FS="|"}{print $3}' list.txt    

Flume

Scala

XYZ

 

# 输出分隔符(OFS、ORS)

[root@VM_0_13_centos ~]#cat list.txt

Hadoop|Spark|Flume--JAVA|Python|Scala|Go--Allen|Mike|XYZ

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $3}' list.txt 

Flume&Scala&XYZ

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $1 $3}' list.txt

HadoopFlume&JAVAScala&AllenXYZ

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $1,$3}' list.txt

Hadoop Flume&JAVA Scala&Allen XYZ

[root@VM_0_13_centos ~]# awk 'BEGIN{RS="--";FS="|";ORS="&";OFS="@"{print $1,$3}' list.txt

Hadoop@Flume&JAVA@Scala&Allen@XYZ

#命令行参数个数

# awk本身作为一个参数,list.txt作为一个参数,所以是两个参数

# awk不指定匹配条件,默认对文本的每一行进行处理,处理每一行都执行{commands},即处理每一行都打印参数个数,所以输出了3个,因为文件有三行

[root@VM_0_13_centos ~]# awk '{print ARGC}' list.txt                           

2

2

2

awk格式化输出之printf

printf的格式说明符

格式符

含义

%s

打印字符串

%d

打印十进制数

%f

打印一个浮点数

%x

打印十六进制数

%o

打印八进制数

%e

打印数字的科学技术法形式

%c

打印单个字符的ASCII码

 

printf的修饰符

修饰符

含义

-

左对齐

+

右对齐

#

显示8进制在前面加0,显示16进制在前面加0x

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{printf "%s\n",$1}' /etc/passwd

root

bin

daemon

adm

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{printf "%s\t%s\n",$1,$7}' /etc/passwd

root    /bin/bash

bin     /sbin/nologin

daemon  /sbin/nologin

adm     /sbin/nologin

# %20s,指定该字符串固定占用20个字符的长度,如果字符数不够20个,用空格补齐

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{printf "%20s%20s\n",$1,$7}' /etc/passwd  

                root           /bin/bash

                 bin       /sbin/nologin

              daemon       /sbin/nologin

                 adm       /sbin/nologin

[root@VM_0_13_centos ~]# awk 'BEGIN{FS=":"}{printf "%-20s%-20s\n",$1,$7}' /etc/passwd

root                /bin/bash          

bin                 /sbin/nologin      

daemon              /sbin/nologin      

adm                 /sbin/nologin

 

格式符示例:

1.以字符串格式打印/etc/passwd中的第7个字段,以”:”作为分隔符

              awk ‘BEGIN{FS=”:”} {printf “%s\n”, $7}’ /etc/passwd

       2.以10进制格式打印/etc/passwd中的第3个字段,以”:”作为分隔符

              awk ‘BEGIN{FS=”:”} {printf “%d\n”, $7}’ /etc/passwd

       3.以浮点数打印/etc/passwd中的第3个字段,以”:”作为分隔符(%0.2f,保留小数点后两位)

              awk ‘BEGIN{FS=”:”} {printf “%0.2f\n”, $7}’ /etc/passwd

       4. 以16进制格式打印/etc/passwd中的第3个字段,以”:”作为分隔符

              awk ‘BEGIN{FS=”:”} {printf “%#x\n”, $7}’ /etc/passwd

       5. 以8进制格式打印/etc/passwd中的第3个字段,以”:”作为分隔符

              awk ‘BEGIN{FS=”:”} {printf “%#o\n”, $7}’ /etc/passwd

       6. 以科学计算法格式打印/etc/passwd中的第3个字段,以”:”作为分隔符

              awk ‘BEGIN{FS=”:”} {printf “%e\n”, $7}’ /etc/passwd

 

修饰符示例

       1.左对齐格式

              awk 'BEGIN{FS=":"}{printf "%-20s%-20s\n",$1,$7}' /etc/passwd

 

awk模式匹配的两种用法

语法格式

含义

RegExp

按正则表达式匹配

关系运算

按关系运算匹配(等于、大于、小于等)

RegExp

       匹配/etc/passwd文件行中含有root字符串的所有行(正则匹配/root/)

              awk ‘BEGIN{FS=”:”}/root/{print $0}’ /etc/passwd

       匹配/etc/passwd文件行中以yarn开头的所有行

              awk ‘BEGIN{FS=”:”}/^yarn/{print $0}’ /etc/passwd

 

 运算符匹配

       关系运算符匹配:

              <     小于

              >     大于

              <=   小于等于

              >=   大于等于

              ==   等于(既可以用于数字,也可以用于字符串)

              !=    不等于(既可以用于数字,也可以用于字符串)

              ~/reg/    匹配正则表达式

              !~/reg/   不匹配正则表达式

  1.以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息

              awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd

  2.以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息

              awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd

       3.以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息

              awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd

       4.以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息

              awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd

       5. 匹配/etc/passwd文件中第3个字段包含3个以上数字的所有行信息

              awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd

 

       布尔运算符匹配

              ||      或

              &&  与

              !      非

       1.以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息

              awk 'BEGIN{FS=":"}$1=="hdfs"||$1=="yarn" {print $0}' /etc/passwd

       2.以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息

              awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd

  3.以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第7个字段包含/bin/bash的所有行信息

              awk 'BEGIN{FS=":"}$3<50 && $7~/\/bin\/bash/ {print $0}' /etc/passwd

 

awk中的表达式用法

awk动作表达式中的算数运算符

运算符

含义

+

-

*

/

%

^或**

乘方

++x

在返回x变量之前,x变量加1

x++

在返回x变量之后,x变量加1

 

awk动作中的条件及循环语句

       条件语句:

    if(条件表达式)

    {

           动作1

    }

              else if(条件表达式)

    {

           动作2

    }

              else

    {

           动作3

    }

      

       循环语句:

              while循环:

                     while(条件表达式)

                     {

                            动作

                     }

 

              do while循环:

                     do

                     {

                            动作

                     }

      while(条件表达式)

 

              for循环:

                     for(初始化计数器;计数器测试;计数器变更)

                     {

        动作

                     }

                    

                     for(i in arr)

                     {

                            动作

      }

 

       1.以:为分隔符,只打印/etc/passwd中第3个字段的数字在50-100范围内的行信息

awk -f scripts.awk /etc/passwd

vim scripts.awk

BEGIN{

  FS=":"

}

 

{

       if($3<50)

       {

              printf "%-20s%-25s%-5d\n","UID<50",$1,$3

}

else if($3>50 && $3<100)

{

       printf "%-20s%-25s%-5d\n","50<UID<100",$1,$3

}

else

{

       printf "%-20s%-25s%-5d\n","UID>100",$1,$3

}

}

2.计算下列每个同学的平均分数,并且只打印平均分数大于90 的同学姓名和分数信息

    Allen              80                  90                  96                  98

              Mike              93                  98                  92                  91

              Zhang           78                  76                  87                  92

              Jerry              86                  89                  68                  92

              Han               85                  95                  75                  90

              Li                   78                  88                  98                  100

 

              vim student.awk

                     BEGIN{

                            printf "%-10s%-10s%-10s%-10s%-10s%-10s\n","Name","Chiness","English","Math","Physical","Average"

      }

                    

                     {

                            total=$2+$3+$4+$5

                            avg=total/4

                            if(avg>90)

                            {

                                   printf "%-10s%-10d%-10d%-10d%-10d%-0.2f\n",$1,$2,$3,$4,$5,avg

 

          # 累加各科分数

                                   score_chinese+=$2

                                   score_english+=$3

                                   score_math+=$4

                                   score_physical+=$5

        }

      }

 

      END{

             printf "%-10s%-10d%-10d%-10d%-10d\n","",score_chinese,score_english,score_math,score_physical

      }

              awk -f student.awk student.txt

 

awk中的字符串函数

 

函数名

解释

函数返回值

length(str)

计算字符串长度

整数长度值

index(str1,str2)

在str1中查找str2的位置

返回值为位置索引,从1计数

tolower(str)

转换为小写

转换后的小写字符串

toupper(str)

转换为大写

转换后的大写字符串

substr(str,m,n)

从str的m个字符开始,截取n位,n不指定默认截取到字符串结尾

截取后的子串

split(str,arr,fs)

按fs切割字符串,结果保存到数组arr中,该数组的下标是从1开始,和shell数组从0开始不一样,fs默认为空格

切割后的子串个数

match(str,/RE/)

在str中按照RE查找,返回位置

返回索引位置

sub(RE,RepStr,str)

在str中搜索符合RE的子串,将其替换为RepStr,只替换第一个匹配到的

替换的个数

gsub(RE,RepStr,str)

在str中搜索符合RE的子串,将其替换为RepStr,替换所有

替换的个数

1.以:为分隔符,返回/etc/passwd中每行中每个字段的长度

BEGIN{

       FS=":"

}

 

{

       i=1

       while(i<=NF)

       {

              if(i==NF)

              {

                     printf "%d",length($i)

}

              else

              {

                     printf "%d:",length($i)

              }

i++

}

printf "\n"

}

 

2.搜索字符串"I have a dream"中出现"ea"子串的位置

       awk 'BEGIN{str="I have a dream";location=index(str,"ea");print location}'

       awk 'BEGIN{str="I have a dream";location=match(str,"ea");print location}'

 

3.将字符串"Hadoop is a bigdata Framework"全部转换成小写

       awk 'BEGIN{str="Hadoop is a bigdata Framework";print tolower(str)}'

 

4.将字符串"Hadoop is a bigdata Framework"全部转换成大写

       awk 'BEGIN{str="Hadoop is a bigdata Framework";print toupper(str)}'

 

5.将字符串"Hadoop Kafka Spark Storm HDFS YARN Zookeeper",按照空格为分隔符,分隔每部分保存到数组arr中

       awk 'BEGIN{str="Hadoop Kafka Spark Storm HDFS YARN Zookeeper";split(str,arr," ");for(a in arr){print arr[a]}}'

 

6.搜索字符串"Tranction 2345 Start:Select * from master"第一个数字出现的位置

       awk 'BEGIN{str="Tranction 2345 Start:Select * from master";location=match(str,/[0-9]/);print location}'

 

7.截取字符串"transaction start"的子串,截取条件从第4个字符开始,截取5位

       awk 'BEGIN{str="transaction start";print substr(str,4,5)}'

 

8.替换字符串"Tranction 243 Start,Event ID:9002"中第一个匹配到的数字串替换为$符号

       awk 'BEGIN{str="Tranction 243 Start,Event ID:9002";count=sub(/[0-9]+/,"$",str);print count,str}'

              1 Tranction $ Start,Event ID:9002

 

awk中的常用选项

选项

解释

-v

参数传递(在向awk中传递变量(awk外定义的变量)的时候,变量都要加双引号)(awk -v num="$num1" -v var1="$var" 'BEGIN{print num,var1}')

-f

指定脚本文件(在命令行模式分割多个命令用分号;,在脚本文件中分割多个命令用换行符)(建议在脚本文件里写,不建议在命令行里写)

-F

指定分隔符

-V

查看awk的版本号

[root@VM_0_13_centos ~]# num1=20

[root@VM_0_13_centos ~]# var="hello world"

[root@VM_0_13_centos ~]# awk 'BEGIN{print $num1}'

 

[root@VM_0_13_centos ~]# awk 'BEGIN{print $var}'

 

[root@VM_0_13_centos ~]# awk -v num=$num1 -v var1=$var 'BEGIN{print num,var1}'

awk: fatal: cannot open file `BEGIN{print num,var1}' for reading (No such file or directory)

[root@VM_0_13_centos ~]# awk -v num=$num1 -v var1="$var" 'BEGIN{print num,var1}'

20 hello world

[root@VM_0_13_centos ~]# awk -v num="$num1" -v var1="$var" 'BEGIN{print num,var1}'

20 hello world

 

# 指定脚本文件执行awk,脚本文件的书写格式

# 注意BEGIN、匹配模式以及END后面的大括号{,必须和BEGIN、匹配模式以及END在同一行

BEGIN{

        printf "%-20s%-10s\n","IP","Count"

}

 

$0!~/^$/{

        if($6!="Accepted")

        {

                ip_list[$11]+=1

        }

}

 

END{

        for(ip in ip_list)

        {

                printf "%-20s%-10d\n",ip,ip_list[ip]

        }

}

 

awk中数组的用法

       shell中数组的用法

              array=("Allen" "Mike" "Messi" "Jerry" "Hanmeimei" "Wang")

              打印元素              echo ${array[2]}    # 下标从0开始

              打印元素个数      echo ${#array[@]}

              打印元素长度      echo ${#array[3]}  # 求字符串长度${#str}

              给元素赋值          array[3]="Li"

              删除元素              unset array[2];unset array

              分片访问              echo ${array[@]:1:3}    # 从数组下标为1的开始,访问后面三个元素;如果3省略,那就直接访问到数组结尾

              元素内容替换             ${array[@]/e/E} 只替换数组中每个元素内的第一个e; ${array[@]//e/E} 替换数组中每个元素内所有的e

              数组遍历

                     for a in ${array[@]}

                     do

                            echo $a

                     done

                     # for a in ${array[@]}; do echo $a; done

      

 

       awk中数组的用法

              在awk中,使用数组时,不仅可以使用1.2…n作为数组下标(下标从1开始),也可以使用字符串作为数组下标

             

              1.当使用1.2.3…n时,直接使用array[n]访问元素;需要遍历数组时,使用以下形式:

                     str="Allen Jerry Mike Tracy Jordan Kobe Garnet"

                     split(str,array," ")

      # 第一种遍历形式

      for(i=1;i<length(array);i++)

                            print array[i]

                    # 第二种遍历形式

                     for(i in array)

                            print array[i]

[root@VM_0_13_centos ~]# awk 'BEGIN{str="Allen Jerry Mike Tracy Jordan Kobe Garnet";split(str,array);for(i=1;i<length(array);i++) print array[i]}'

Allen

Jerry

Mike

Tracy

Jordan

Kobe

[root@VM_0_13_centos ~]# awk 'BEGIN{str="Allen Jerry Mike Tracy Jordan Kobe Garnet";split(str,array);for(a in array) print array[a]}'            

Tracy

Jordan

Kobe

Garnet

Allen

Jerry

Mike   

              2.当使用字符串作为数组下标时,需要使用array[str]形式访问元素;遍历数组时,使用以下形式:

                     array["var1"]="Jin"

                     array["var2"]="Hao"

                     array["var3"]="Fang"

       # 字符串作为数组下标的遍历形式,只有这一种

                     for(a in array)

                            print array[a]

[root@VM_0_13_centos ~]# awk 'BEGIN{array["var1"]="Jin";array["var2"]="Hao";array["var3"]="Fang";for(a in array){print array[a]}}'
Jin
Hao
Fang

 

典型常用例子

       1.统计主机上所有的TCP连接状态数,按照每个TCP状态分类

       # array[$6]++,使用$6这个字段的字符串作为数组的下标,值未定义默认为0,当遇到相同的字符串下标时,就对这个下标对应的数组中元素值加1,如果遇到不同的字符串下标,那就会以这个下标在数组中新增一个元素

[root@VM_0_13_centos ~]# netstat -an | grep tcp | awk '{array[$6]++}END{for(a in array) print a,array[a]}'

LISTEN 4

ESTABLISHED 2

TIME_WAIT 9

 

       2.计算横向数据总和,计算纵向数据总和

Allen             80                 90                 96                 98

              Mike             93                 98                 92                 91

              Zhang           78                 76                 87                 92

              Jerry              86                 89                 68                 92

              Han               85                 95                 75                 90

              Li                   78                 88                 98                 100

[root@VM_0_13_centos ~]# cat student.awk               

BEGIN{

        printf "%-10s%-10s%-10s%-10s%-10s%-10s\n","Name","YuWen","Math","English","Physical","Total"

}

 

{

        total=$2+$3+$4+$5

        yuwen_sum+=$2

        math_sum+=$3

        english_sum+=$4

        physical_sum+=$5

        printf "%-10s%-10d%-10d%-10d%-10d%-10d\n",$1,$2,$3,$4,$5,total

}

 

END{

        printf "%-10s%-10d%-10d%-10d%-10d\n","",yuwen_sum,math_sum,english_sum,physical_sum

}

[root@VM_0_13_centos ~]# awk -f student.awk student.txt

Name      YuWen     Math      English   Physical  Total    

Allen     80        90        96        98        364      

Mike      93        98        92        91        374      

Zhang     78        76        87        92        333      

Jerry     86        89        68        92        335      

Han       85        95        75        90        345      

Li        78        88        98        100       364      

          500       536       516       563       

 

3.利用awk处理日志,并生成结果报告

       生成数据脚本insert.sh,内容如下

#!/bin/bash

 

function create_random()

{

        min=$1

        max=$(($2-$min+1))

        num=$(date +%s%N)

        echo $(($num%$max+$min))

}

 

INDEX=1

 

while true

do

        for user in allen mike jerry tracy han lilei

        do

                # $RANDOM is shell Built-in variable, it can generate a random number, range is [0, 32767]

                COUNT=$RANDOM

                NUM1=`create_random 1 $COUNT`

                NUM2=`expr $COUNT - $NUM1`

                echo "`date '+%Y-%m-%d %H:%M:%S'` $INDEX Batches: user $user insert $COUNT records into database:product table:detail, insert $NUM1 records successfully, failed $NUM2 records" >> ./db.log.`date +%Y%m%d`

                INDEX=`expr $INDEX + 1`

        done

done

 

       数据格式如下:

2019-02-19 13:17:29 1 Batches: user allen insert 15145 records into database:product table:detail, insert 3995 records successfully, failed 11150 records

2019-02-19 13:17:29 2 Batches: user mike insert 8083 records into database:product table:detail, insert 3453 records successfully, failed 4630 records

2019-02-19 13:17:29 3 Batches: user jerry insert 31794 records into database:product table:detail, insert 9663 records successfully, failed 22131 records

2019-02-19 13:17:29 4 Batches: user tracy insert 24121 records into database:product table:detail, insert 21716 records successfully, failed 2405 records

 

1.统计每个人员分别插入了多少条record进数据库

       输出结果:

              USER      TOTAL_RECORDS

              allen      490990

              mike      323339

[root@VM_0_13_centos awk]# cat db.awk 
BEGIN{
printf "%-10s%-20s\n","USER","TOTAL_RECORDS"
}

{
user[$6]+=$8
}
END{
for(u in user)
{
printf "%-10s%-20d\n",u,user[u]
}
}

[root@VM_0_13_centos awk]# awk -f db.awk db.log.20190311
USER TOTAL_RECORDS
tracy 187533387
allen 188668476
mike 188232914
jerry 186532169
lilei 187869349
han 186615719

2.统计每个人分别成功插入了多少条记录,以及失败了多少条记录

[root@VM_0_13_centos awk]# cat db.awk
BEGIN{
printf "%-10s%-20s%-20s%-20s\n","USER","TOTAL_RECORDS","SUCCESS","FAILED"
}

{
user[$6]+=$8
user_success[$6]+=$14
user_failed[$6]+=$18
}
END{
for(u in user)
{
printf "%-10s%-20d%-20d%-20d\n",u,user[u],user_success[u],user_failed[u]
}
}
[root@VM_0_13_centos awk]# awk -f db.awk db.log.20190311
USER TOTAL_RECORDS SUCCESS FAILED
tracy 187533387 94745135 92788252
allen 188668476 93087694 95580782
mike 188232914 94174991 94057923
jerry 186532169 92814601 93717568
lilei 187869349 92863157 95006192
han 186615719 93822553 92793166

4.在例子3的基础上,加上结尾,统计全部插入记录数,成功记录数,失败记录数

[root@VM_0_13_centos awk]# cat db.awk
BEGIN{
printf "%-10s%-20s%-20s%-20s\n","USER","TOTAL_RECORDS","SUCCESS","FAILED"
}

{
user[$6]+=$8
user_success[$6]+=$14
user_failed[$6]+=$18
}
END{
for(u in user)
{
total+=user[u]
total_success+=user_success[$6]
total_failed+=user_failed[$6]
printf "%-10s%-20d%-20d%-20d\n",u,user[u],user_success[u],user_failed[u]
}
printf "%-20s%-20s%-20s\n","TOTAL","TOTAL_SUCCESS","TOTAL_FAILED"
printf "%-20d%-20d%-20d\n",total,total_success,total_failed
}
[root@VM_0_13_centos awk]# awk -f db.awk db.log.20190311
USER TOTAL_RECORDS SUCCESS FAILED
tracy 187533387 94745135 92788252
allen 188668476 93087694 95580782
mike 188232914 94174991 94057923
jerry 186532169 92814601 93717568
lilei 187869349 92863157 95006192
han 186615719 93822553 92793166
TOTAL TOTAL_SUCCESS TOTAL_FAILED
1125452014 558526164 573484692

5.查找丢失数据的现象,也就是成功+失败的记录数,不等于一共插入的记录数。找出这些数据并输出结果:

[root@VM_0_13_centos awk]# awk '{if($8!=$14+$18){print NR,$0}}' db.log.20190311
9 2019-03-11 21:33:39 9 Batches: user jerry insert 31131 records into database:product table:detail, insert 13966 records successfully, failed 1716 records
899 2019-03-11 21:33:44 899 Batches: user han insert 4638 records into database:product table:detail, insert 29611 records successfully, failed 1678 records



posted @ 2019-03-11 22:17  小宇子2B  阅读(207)  评论(0编辑  收藏  举报