首先来巩固一下CU的两个sed例子
例一
格式如下所示的一个ini文件
[a]
p1=k1,k2,k3,k4,.....k9
P2=m1,m2,m3,m4,....m9
......
p9=z1,z1,z3,z4,.....z9
[b]
p1=k1,k2,k3,k4,.....k9
P2=m1,m2,m3,m4,....m9
......
p9=z1,z1,z3,z4,.....z9
[c]
p1=k1,k2,k3,k4,.....k9
P2=m1,m2,m3,m4,....m9
......
p9=z1,z1,z3,z4,.....z9
[d]
.......
如何取到b下面的p2行的m3和m4的值??
ly5066113给出的awk
awk -v RS="[" '/^b]/{split($3,a,",");print a[3],a[4]}' urfile
这个变量 RS 用得很巧啊。
RS 用 [ 为分隔符,这样的用法使得$3 变成 P2=m1,m2,m3,m4,....m9
整个语句就变成,以[ 为分割,找出b 开头的纪录:
b]
p1=k1,k2,k3,k4,.....k9
P2=m1,m2,m3,m4,....m9
......
p9=z1,z1,z3,z4,.....z9
将$3 (P2=m1,m2,m3,m4,....m9) 按逗号分割给数组a,最后输出 a[3] 和a[4].
例二
文本内容
a.txt
type {
sfjslkfjslfjslf
lsjflsfjslfjs
sljfslfjslf
}aa
type {
sfkhsfkshf
141414lsjflsfjmb
s474ljfslfjslfm54
}bb
type {
098dgs
vnxvsb
zczgmvs
}cc
type {
blddgdlgj
d;gkdgkd
lkdjgld
}bb
...
现从文本a.txt中取出 type{...}bb的内容
结果:
type {
sfkhsfkshf
141414lsjflsfjmb
s474ljfslfjslfm54
}bb
type {
blddgdlgj
d;gkdgkd
lkdjgld
}bb
ly5066113给出的awk
awk -v RS="" '/}bb/' a.txt
可能看完这两个ly5066113给出的awk还会有疑问,
我对RS的理解,RS是作为输入分隔符默认是\n,awk又是一行一行的处理,那么例子第一段可以这样分解
[a]\np1=k1,k2,k3,k4,.....k9\nP2=m1,m2,m3,m4,....m9\n......\np9=z1,z1,z3,z4,.....z9\n
以\n为字段分隔符被分解成几段,这样来看就一目了然!
到了这里可能还会有这样的疑问字段分隔符FS怎么变成\n了,之前也并没有指定啊,
(FS不指定默认是空格或者TAB)
再举一个更加直观的例子
[a]
this a aaa this后面多加了一个空格,a和aaa之间是一个tab
is
a
test
[b]
this b bbb
is
another
test
[c]
this c ccc
is
also
a
test
awk -v RS="[" '{print $3}'
awk -v RS="[" '{print $4}'
awk -v RS="[" '{print $5}'
输出发现FS 空格 TAB \n 三者皆有哦
实例三
[root@test ~]# cat a
a
b
c
d
e
f
1
2
3
4
5
[root@test ~]# tac a
5
4
3
2
1
f
e
d
c
b
a
[root@test ~]# tac a |sed -n 2p
4
awk -v RS="###" '{print $(NF-1)}'
解释一下RS="###" 的作用,是一直找不到结束的分隔符,所以把所有的行都变成了一行,再输出倒数第二个字段