【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战

目录:
(九)两个文件合并
(十)关于NFS权限的设置
(十一)求交集
(十二)统计字符出现的次数
(十三)求和
(十四)案例实战


(九)两个文件合并
(9.1)首先我们在系统中定义两个文件a1和a2,现在我们的需求是使用a1的第二个字段去比对a2的第二个字段,如果相同,则将a1的第一个字段添加到a2文件的第三个字段上,最终以a2文件为模板打印出对应的信息,如果多个文件进行合并可以考虑使用数组
# awk -F"[ ,]" 'NR==FNR{a[$2]=$1}NR!=FNR{print $0,a[$2]}' a1 a2
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(9.2)我们创建两个文件b1和b2,现在我们希望将两个文件合并为如下的格式,我们发现b1的第二列和b2的第一列是共同项,然后我们在当NR不等于FNR的时候,会进行打印的操作,记得在字段之间使用“:”冒号进行分隔。
我们希望打印的结果如下:
tom:001:aa
tom:001:bb
bob:002:cc
bob:002:dd
# awk -F: 'NR==FNR{a[$2]=$0}NR!=FNR{print a[$1]":"$2}' b1 b2
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(9.3)我们创建一个c1和c2文件,如果c1的$1和c2的$3相同,c1的$2和c2的$4的后三个字符相同,c1的$3和c2的$6相同,那么打印c2中符合条件的行,如果需求是筛选多个共同列,我们只要把这多个共同列进行合并比较即可。我们发现c1中的第1列加第2列加第3列与c2文件中的第3列加第4列后三个字符加第6列,如果是相同的,那么就符合需求,可以将c2文件中的当前行打印出来。
# awk 'NR==FNR{a[$1]=$1$2$3}NR!=FNR{X=substr($4,3);Y=$3X$6;if(Y==a[$3]){print}}' c1 c2
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(9.4)我们创建一个文件d1和d2,此时我们希望将d2文件中的第2个字段替换到d1文件的第2个字段,首先要注意在使用文件名时要先用d2然后使用d1,同时指定输入和输出的分隔符都为“:”冒号,然后执行将d2文件中的第2个字段替换到d1文件的第2个字段的操作。
# awk -F: 'BEGIN{FS=OFS=":"}NR==FNR{a[$1]=$2}NR!=FNR{$2=a[$1];print}' d2 d1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战


(十)相同行合并为一行
(10.1)我们创建一个文本文件aa1,现在我们的需求是将一个文件中将拥有相同字段的行合并成一行,例如第一行第1个字段是27,第二行第1个字段也是27,则将第二行第2个字段的信息直接打印在第一行第3个字段的位置,第三行第1个字段是26,所以直接打印到下一行,以此类推。首先使用NR是否等于1来进行判断,如果NR为1则打印当前行并将第一行第1个字段赋值给变量x,接着是第二行,发现NR不等于1了,但是第二行第1个字段等于变量x的值,所以此时用printf打印此" %s"格式,然后处理第三行,我们发现符合“else if($1!=x)”这个条件,所以此时我们会先打印一个换行符“\n”然后再打印这一整行的内容,并将当前行的第1个字段赋值给变量x,这样我们就基本可以实现我们所需求的格式了。
# awk 'NR==1{printf "%s", $0;x=$1}NR!=1{if($1==x){printf " %s", $2}else if($1!=x){printf "\n%s", $0;x=$1}}END{printf "\n"}' aa1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战


(十一)求交集
(11.1)现在我们创建了两个文件a1和a2,现在要求打印a1文件中的一些行,a1的第2字段出现在a2的第1个字段中,现在如果要求a的某部分是否出现在b的某部分里的时候,那么我们就把b的那部分设置为数组的下标,然后判断a的那部分是否是下标的一个元素。此时则应该为“awk -F”[,/]” ‘’ a2 a1”
# awk -F"[,/]" 'NR==FNR{a[$1]=$0}NR!=FNR{if($2 in a){print $0}}' a2 a1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(11.2)现在我们创建两个文件b1和b2,现在我们的需求是打印b1的一些行,b1的$1出现在b2的第1个字段里,找到那些行之后,并把b2里对应的这些行的$2部分进行求和,我们可以先在b2文件中将所有的第1字段的第2个字段值进行相加操作,最后在b1文件行打印出来时也把相加的值一同打印出来。
# awk -F, 'NR==FNR{a[$1]+=$2}NR!=FNR{if($1 in a){printf "%s,%f\n",$0,a[$1]}}' b2 b1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战


(十二)统计字符出现的次数
(12.1)我们有一个文件a1,现在我们需要统计每个字符在文本文件中出现的次数,此时我们的思路是遇到一个字段就将其设置为一个元素的下标,当我们已经定义了一个元素时,如果下次再遇到这个下标的元素的时候,则加上1次。我们首先是使用循环遍历每一行,使用遍历的字段作为数组的下标,如果后面出现了相同的字段,则将统计的结果加1,然后在END中去遍历数组中每个元素当前的数值,此时就可以得到每个字符在文本文件中出现的次数。
# awk '{for(i=1;i<=NF;i++){a[$i]++}}END{for(x in a){print x"一共出现了"a[x]"次"}}' a1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战


(十三)求和
(13.1)在我们的内存中正常是会将内存的数据写入到硬盘中的,因此内存的数据和硬盘的数据是同步的,我们称之为干净数据,但是有时候在我们的内存中有些数据修改完后并没有写入到硬盘中去,内存中的数据和硬盘数据并不同步,此时这类数据我们称之为脏数据,如果脏数据没有及时写入到硬盘,那么当计算机重启之后没有写入到硬盘的数据就会丢失了。现在我们的需求是计算出某个进程一共有多少个干净页,有多少个脏页,我们是可以从/proc/1/smaps的系统映射文件中查看到我们所需的内存相关信息的,我们可以使用模式匹配的方式,将干净页和脏页分别进行统计,在之前的基础上进行连加操作。
# cat /proc/1/smaps
# cat /proc/1/smaps | awk '/Shared_Clean/{AA+=$2}/Shared_Dirty/{BB+=$2}END{print "干净页总合是"AA"KB";print "脏页的总合是"BB"KB"}'
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(13.2)现在我们有两个文件a1和a2,因为我们发现a1文件和a2文件的列数是一样的,所以现在我们的需求是希望将a1文件和a2文件中对应的列数进行相加得到一个相加后的一行数组。解决这个问题的思路我们是把一个文件里所有的数字放在一个数组里保存,然后读取第二个文件,把第二个文件里所有的数组保存,然后分别相加(图13-5)。当然我们也可以使用getline函数解决问题,首先使用for循环获取a1文件的所有值,然后使用getline读取a2文件读取的行替换到当前所在行的信息,最后使用for循环去遍历数组a与当前a2文件中的每个字段,并进行相加的操作,此时也可以得到我们所需的结果(图)。
# awk 'NR==FNR{for(i=1;i<=NF;i++){a[i]=$i}}NR!=FNR{for(i=1;i<=NF;i++){b[i]=$i;printf "%s ",a[i]+b[i]}}END{printf "\n"}' a1 a2
# awk '{for(i=1;i<=NF;i++){a[i]=$i};getline < "a2";for(i=1;i<=NF;i++){printf "%s ",a[i]+$i}printf "\n"}' a1
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战


(十四)案例实战
(14.1)取得网卡的IP
# ifconfig | grep 'inet' | grep broadcast | awk '{print $2}'
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(14.2)取得系统内存大小
# cat /proc/meminfo | awk '/MemTotal/{print $2}'
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
(14.3)修改CSV文件各字段的顺序,我们先在系统中创建一个data.csv的文件,想要把第2个字段和第4个字段进行调换。
# cat data.csv | awk -F, 'BEGIN{OFS=","} {print $1,$4,$3,$2,$5,$6,$7}'
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战
【讲清楚,说明白!】Linux从业人员必备工具(二)--AWK文本处理利器实战

—————— 本文至此结束,感谢阅读 ——————

猜你喜欢

转载自blog.51cto.com/13613726/2460753