学习有时候就是一个不断积累,不断实践,不断重复的过程,要想技艺娴熟,必下一番功夫。积累很重要,本文会持续收集一些awk and sed文本分析问题,主要来时CU和相关讨论群,并附上自己的解决方法。实践,提高,记录,有更好或是简便的方法欢迎评论告知~
ex1 字段间内容删除
[[email protected] awk_and_sed]# more t1
/*aaaa*/ /*bbbbb*/ /*ccccc*/
aaaaa
/*bbbbb
1111111
* bbbbbb*/
bbbbb
/*cccc*/
ccc
#========================
#要求去掉/* */里面包含的内容
思路:创建一个循环,匹配/*的就不断把下一行拉上来,直到/* */成对出现后删除。
[[email protected] awk_and_sed]# sed ':a;N;s/\/\*.*\*\///;/\/\*/ba' t1
aaaaa
bbbbb
ccc
ex2 打印前后行
[[email protected] awk_and_sed]# more t2
interface GigabitEthernet2/42
interface GigabitEthernet2/44
interface GigabitEthernet2/46
ip address 192.168.1.1 255.255.255.248
interface GigabitEthernet5/1
interface GigabitEthernet5/3
ip address 192.168.2.1 255.255.255.248
==========================
要求:输出ip 和 上一行的接口
思路:匹配非ip的行则把该行保存到临时变量中,继续读下一行,直到匹配到接口则把变量和接口行一起打印。
[[email protected] awk_and_sed]# awk '!/ip/{temp=$0;next}{print temp"\n"$0}' t2
interface GigabitEthernet2/46
ip address 192.168.1.1 255.255.255.248
interface GigabitEthernet5/3
ip address 192.168.2.1 255.255.255.248
[[email protected] awk_and_sed]# sed ':a;N;/ip/b;D;ta' t2 #循环拉下一行,直到匹配到IP则退出并打印模式空间的内容,否则删除模式空间的第一行。
interface GigabitEthernet2/46
ip address 192.168.1.1 255.255.255.248
interface GigabitEthernet5/3
ip address 192.168.2.1 255.255.255.248
ex3 连续关联行判断,赋值
[[email protected] awk_and_sed]# more t4
chr11 19231997 19231998 NM_003476.4 CSRP3 5U3E
chr11 19231998 19231999 NM_003476.4 CSRP3 5U3E
chr11 19232000 19232001 NM_003476.4 CSRP3 5U3E
chr11 19232001 19232002 NM_003476.4 CSRP3 C1
chr11 19232002 19232003 NM_003476.5 CSRP3 C1
chr11 19232003 19232004 NM_003476.5 CSRP3 C1
chr11 19232004 19232005 NM_003476.5 CSRP3 C1
==========================
要求:如果第4,6列相同,则判断第2,3列是否连续,如果连续则保留第2列的开头,第3列的结尾。 #把$2保存到变量,符合条件的行,$2赋值为变量。
[[email protected] awk_and_sed]# awk '{f=($2==t && p=="$4$6")?f:$2 ;$2=f;a[f]=$0;t=$3;p="$4$6"}END{for(i in a)print a[i]}' t4
chr11 19231997 19231999 NM_003476.4 CSRP3 5U3E
chr11 19232000 19232005 NM_003476.5 CSRP3 C1
ex4 灵活的RS
---------
PID=2310
ARG1=8
ARG2=9
---------
PID=2320
ARG1=10
---------
NAME=test.x
ARG1=23
--------
PID=2330
ARG1=8
========================
要求,如输出ARG1=8 则打印出有ARG1=8的虚线框里的内容。
思路:可以利用awk的RS,默认是"\n"
[[email protected] awk_and_sed]# awk -vRS='-+' '/ARG1=8/' t6
PID=2310
ARG1=8
ARG2=9
PID=2330
ARG1=8
ex5 输出统计,打印第N次输出
[AUTO_MONITOR]$ more file
Linux 2.6.18-8.el5 (xm35) 03/25/2014
09:23:56 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
09:23:57 PM all 0.50 0.00 1.00 0.00 0.00 0.25 0.00 98.25 2725.25
09:23:57 PM 0 1.01 0.00 2.02 0.00 0.00 1.01 0.00 95.96 1713.13
09:23:57 PM 1 1.00 0.00 0.00 0.00 0.00 0.00 0.00 99.00 0.00
09:23:57 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 0.00
09:23:57 PM 3 0.00 0.00 1.00 0.00 0.00 0.00 0.00 99.00 1012.12
09:23:57 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
09:23:58 PM all 1.00 0.00 1.25 2.49 0.25 0.25 0.00 94.76 2755.56
09:23:58 PM 0 1.01 0.00 2.02 0.00 1.01 1.01 0.00 94.95 1715.15
09:23:58 PM 1 0.00 0.00 0.00 10.10 0.00 0.00 0.00 89.90 27.27
09:23:58 PM 2 1.98 0.00 1.98 0.00 0.00 0.00 0.00 96.04 0.00
09:23:58 PM 3 0.00 0.00 1.00 0.00 0.00 0.00 0.00 99.00 1012.12
09:23:58 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
09:23:59 PM all 1.00 0.00 1.50 0.00 0.00 0.50 0.00 97.00 2719.80
09:23:59 PM 0 1.98 0.00 2.97 0.00 0.00 1.98 0.00 93.07 1728.71
09:23:59 PM 1 0.00 0.00 0.99 0.00 0.00 0.00 0.00 99.01 0.00
09:23:59 PM 2 1.00 0.00 2.00 0.00 0.00 0.00 0.00 97.00 0.00
09:23:59 PM 3 2.00 0.00 1.00 0.00 0.00 0.00 0.00 97.00 991.09
Average: CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
Average: all 0.83 0.00 1.25 0.83 0.08 0.33 0.00 96.67 2733.44
Average: 0 1.34 0.00 2.34 0.00 0.33 1.34 0.00 94.65 1719.06
Average: 1 0.33 0.00 0.33 3.33 0.00 0.00 0.00 96.00 9.03
Average: 2 1.00 0.00 1.33 0.00 0.00 0.00 0.00 97.67 0.00
Average: 3 0.67 0.00 1.00 0.00 0.00 0.00 0.00 98.33 1005.02
=========================
要求 打印出第三个 mpstat统计信息!
1. sed 实现,相对复杂,这里采用打点计数法
[ AUTO_MONITOR]$ sed '/CPU/{x;s/^/./;/^.\{3\}$/{x;b};ta};x;/^.\{3\}$/{x;b};:a;x;;d;' file
09:23:58 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
09:23:59 PM all 1.00 0.00 1.50 0.00 0.00 0.50 0.00 97.00 2719.80
09:23:59 PM 0 1.98 0.00 2.97 0.00 0.00 1.98 0.00 93.07 1728.71
09:23:59 PM 1 0.00 0.00 0.99 0.00 0.00 0.00 0.00 99.01 0.00
09:23:59 PM 2 1.00 0.00 2.00 0.00 0.00 0.00 0.00 97.00 0.00
09:23:59 PM 3 2.00 0.00 1.00 0.00 0.00 0.00 0.00 97.00 991.09
2. awk 实现,这就比较简单了!
[AUTO_MONITOR]$ awk '/CPU/{c++}{if(c==3)print}' file
09:23:58 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
09:23:59 PM all 1.00 0.00 1.50 0.00 0.00 0.50 0.00 97.00 2719.80
09:23:59 PM 0 1.98 0.00 2.97 0.00 0.00 1.98 0.00 93.07 1728.71
09:23:59 PM 1 0.00 0.00 0.99 0.00 0.00 0.00 0.00 99.01 0.00
09:23:59 PM 2 1.00 0.00 2.00 0.00 0.00 0.00 0.00 97.00 0.00
09:23:59 PM 3 2.00 0.00 1.00 0.00 0.00 0.00 0.00 97.00 991.09
ex6 特定字段间内容匹配
[[email protected] ~]# more c
11111111a24802123bc111111
111111a*23sdf111111111111
11bc111111111111111111111
======
要求 打印a到第一个bc这之间的内容。
1. awk 方法,利用RS正则,RT匹配,很是方便。
[[email protected] ~]# awk 'BEGIN{RS="a[^bc]*bc"}{print RT}' c
a24802123bc
a*23sdf111111111111
11bc
2. sed 方式,跨行需要判断。
[[email protected] ~]# sed '/a/{:1;s/.*\(a[^bc]*bc\).*/\1/;t;N;b1}' c
a24802123bc
a*23sdf111111111111
11bc
ex7 多行求和
==
[[email protected] awk_and_sed]# more t7
1 2 3 4 5
1 3 5 7 9
1 1 1 1 1
2 2 2 2 2
4 4 4 4 4
6 6 6 6 6
9 7 5 3 1
5 4 3 2 1
1 1 1 1 1
==
要求: 每3行对应的列求和,这里一共9行,最后输出结果为3行。
[[email protected] awk_and_sed]# awk '{for(i=1;i<=NF;i++)sum[i]+=$i}!(NR%3){for(i=1;i<=NF;i++)$i=sum[i];print;delete sum}' t7
3 6 9 12 15
12 12 12 12 12
15 12 9 6 3
注释:NR%3=> NR为3的整数倍时,为0;delete 删除变量;这里思路就是NR符合3的倍数时打印出sum值,然后删除sum,相当于清0,非3倍数时,sum+=$i
<pre code_snippet_id="238548" snippet_file_name="blog_20140401_7_7412752" name="code" class="html">ex8 sed 回溯引用以及临时换符
[[email protected] awk_and_sed]# more t10
avg-cpu: %user %nice %system %iowait %steal %idle
0.15 0.09 3.24 0.08 0.00 96.43
=====
要求结果:
avg-cpu: user 0.15 nice 0.09 system 3.24 iowait 0.08 steal 0.00 idle 96.43
awk的话比较简单,这里采用sed 的回溯引用。
[[email protected] awk_and_sed]# sed -r 'N;:a;s/%/@/;s/(.*@\S+)(.*\n *)(\S+)(.*)/\1 \3\2\4/;ta;s/@//g' t10
avg-cpu: user 0.15 nice 0.09 system 3.24 iowait 0.08 steal 0.00 idle 96.43
<pre code_snippet_id="238548" snippet_file_name="blog_20140401_7_7412752" name="code" class="html">ex9 求列平均值
[[email protected] ~]# more a
a 2
a 1
b 1
d 3
d 2
========
要求 取第一列相同元素的平均值,放于第三列
(1)
[[email protected] ~]# awk '{i++;a[i]=$0;b[i]=$1;c[$1]+=$2;d[$1]++}END{for(j=1;j<=i;j++)print a[j]"\t"c[b[j]]/d[b[j]]}' a
a 2 1.5
a 1 1.5
b 1 1
d 3 2.5
d 2 2.5
(2)
[[email protected] ~]# awk 'NR==FNR{s[$1]+=$2;c[$1]++;next}{print $0"\t"s[$1]/c[$1]}' a a
a 2 1.5
a 1 1.5
b 1 1
d 3 2.5
d 2 2.5