AWK 专家必备的12个技巧案例1:字符切割案例2:格式化输出案例3:不显示文件最后一行案例4:不显示最后一列案例5:多列求和案例6:求每行最大值/最小值/平均值案例7:awk的三元表达式案例8:打印第一列相同且第二列最大的行案例9:多列比较求最大值案例10:除第一列外所有值求和案例11:构建不同文件相同列的映射关系案例12:行列调换/矩阵转换案例13:不同文件相同字段匹配至同一个文件,空字段补齐
index函数
知识点: #index 简介➔ Index(s,t) 返回子串t在字符串s中的位置,如果没有指定s,返回0
awk '
BEGIN{
##定义变量x
x="abc def";
##awk中变量直接引用,无需$引用
part=index(x,"b");
##打印从b位置开始后的4个字符-包括b位置
print substr(x,part,4)
}'
结果:
substr函数
知识点: substr简介➔Substr(s,p,n) 返回字符串s中从位置p开始长度为n的子串.如果没有给出n,返回从p开始剩余的字符串
awk '
BEGIN{
##定义变量x
x="1234567";
##打印从第二个字符开始所有字符
part1=substr(x,2);
print part1,"..."
}'
awk 'bash
BEGIN{
x="1234567";
##打印从第二个字符开始,后3个字符
part1=substr(x,2,3);
print part1,"..."
}'
结果:
知识点: printf()函数
# cat ../test_tem/grade
john 10 3 78 94 88
andrea 20 90 75 90 86
jasper 90 150 90 92 84
apple 90 85 76 90 87
sun 60 50 80 98 87
month 100 120 130 80 90
sam 90 85 78 92 90
# cat my_student_avg
BEGIN{ OFS = "\t"
format="|%-8s|\t|%-8s|\t|%-6s|\t|%-2s|\n"
print "*******************************************************"
printf format,"name","S_total","S_avg","grade"
print "*******************************************************"
}
{
student_total=0
for (i=2;i<=NF;i++){
student_total+=$i
total+=$i
avg=student_total/(NF-1)
student_avg[NR]=avg
}
#student_avg[NR]=student_total/(NF-1)
if (avg>=90) grade="A"
else if (avg>=80) grade="B"
else if (avg>=70) grade="C"
else if (avg>=60) grade="D"
else grade="F"
++class_grade[grade]
printf format,$1,student_total,avg,grade #student_avg[NR]
#print "__________________"
#print "avg:",avg,"bbbbbbskdljflkflsjgkl"
}
END{
for (x=1;x<=NR;x++){
class_total_avg+=student_avg[x]
class_avg=class_total_avg/NR
}
for (y=1;y<=NR;y++){
print "student:",student_avg[y],"class_avg",class_avg
if (student_avg[y]>class_avg)
++above_average
else
++below_average
}
for (same_grade_sort in class_grade){
print same_grade_sort ":",class_grade[same_grade_sort]|"sort"
}
#print "END:class_total_avg:",class_total_avg
print "END:class_avg:",class_avg
print "END:above_average:",above_average
print "END:below_average:",below_average
}
结果:
知识点: 内置函数巧用
awk 'NR != 1' file
awk 'BEGIN{OFS="";ORS=""}{for(i=1;i<NF;i++){printf $i" "}{print "\n"}}' file
awk 'NF--{print NF}' file
知识点: 二维数组
# cat file
85 92 78 94 88
89 90 75 90 86
84 88 90 92 84
awk '
{ ##主体函数以"{"开始
for(i=1;i<NF;i++) ##设置循环体,
{a[NR]+=$i} ##赋值到数组,
} ##主体函数"}"闭合
END{ ##END函数
for(i in a) ##读取数组
{print i,a[i]} ##打印数key,及value
}' file
结果
awk '
{ ##主体函数以"{"开始
max=-65535 ##设变量max[awk会自动判断变量类型]
for(i=1;i<=NF;i++) ##设置循环体,
{max=($i>max)? $i:max} ##awk 三元表达式 如果$i>max 则max=$i,否则max=max
print max ##打印出来max
}' file
结果
awk '
{min=65535;
for(i=1;i<=NF;i++)
{min=($i<min)? $i:min};
print min
}' file
结果
知识点: 三元表达式 awk '{print ($1<$2) ? "true" : "false"}'
结果
知识点: 三元表达式
awk '
{
a[$1]=(a[$1]>$2)?a[$1]:$2 ####三元表达式
}END{
for(i in a)
{print i,a[i]}
}' d
结果
知识点: 二维数组&三元表达式
awk '
{
max=0;
for(i=1;i<=NF;i++)
{max=($i>max)? $i:max}
;print max
}' file
结果
awk '
{
for(i=2;i<=NF;i++)
{a[$1]+=$i}
}END{
for(i in a)
{print i,a[i]}
}' grade
结果
知识点: 没有知识点,多练~
awk '
NR==FNR {a[$2]=$1}
NR>FNR && ($4 in a){print $1,$2,$3,a[$4],$5
}' replace ../test_tem/ruku_conf_tmp
# cat replace
001 1
002 2
009 9
010 10
031 31
015 15
008 8
007 7
006 6
039 39
040 40
032 32
036 36
037 37
# cat ../test_tem/ruku_conf_tmp
10.158.143.22 pass 10.158.148.36 1 10.158.145.12
10.158.143.23 pass 10.158.148.36 2 10.158.145.13
10.158.143.24 pass 10.158.148.36 9 10.158.145.14
10.158.143.92 pass 10.158.150.17 10 10.158.145.15
10.158.168.11 pass 10.158.150.17 15 10.158.145.16
10.158.168.12 pass 10.158.150.17 31 10.158.145.17
10.158.164.28 pass 10.158.150.16 32 10.158.145.25
10.158.164.27 pass 10.158.150.16 36 10.158.145.36
10.158.143.25 pass 10.158.147.20 37 10.158.145.24
10.158.164.29 pass 10.158.150.19 39 10.158.146.26
10.158.164.30 pass 10.158.150.19 40 10.158.146.27
结果
需求如图:
处理
awk '
BEGIN{min=0};
NR==FNR{cc[$2]=$1};
NR>FNR&&($1 in cc){a[$1]=(min>$2)?min:$2
}END{
for(i in a)
if(i in cc)
{print i,a[i]}
}' cainhe1 cainhe2
结果
awk 'NR==FNR{a[$1]=$2};NR>FNR{a[$1]?a[$1]=a[$1]" "$2:a[$1]=a[$1]" $ "$2}END{for(i in a){print i,a[i]}}' ../test_tem/e ../test_tem/c
结果: