现在的位置: 首页 > 综合 > 正文

一个稍微复杂的awk & sed应用

2013年12月19日 ⁄ 综合 ⁄ 共 4320字 ⁄ 字号 评论关闭

最近做了一个文本
CDR
转换器,从
A
样式转换为
B
样式,如下所示。

 

A

样式


 

B

样式


 

 

A

样式到

B

样式的转换要点如下:


1.    


header

trailer
都可直接转换,但是
B
样式需要加上
CDR
的计数

2.    


B
样式的
header
还含有
record type
,需要从
A
样式的某个注释行中获取

3.    


字段域的转换比较简单,都是一行对一行

4.    


A
样式有注释行,转换时要全部删除

 

转换由

awk



sed

完成,完整的命令是这样的:


awk 'BEGIN { cnt=0; } { if ( $0 == "RECORD" ) { cnt++;
printf("Record (%d)/n", cnt); } else if ( $0 == "." ) {
printf("End of Record (%d)/n", cnt); } else { print $0; } }' layout_a
| sed '/^Record/{N;N;N;s//n//g;}' | sed 's/^/(Record (.*)/).*input_type
/(.*/)$//1 "/2"/;s/^F /(.*/) /(.*/)$/  
"/1" = "/2"/;/^#/d' > layout b

 

具体解析如下:


1.   

awk 'BEGIN { cnt=0; } {
if ( $0 == "RECORD" ) { cnt++; printf("Record (%d)/n",
cnt); } else if ( $0 == "." ) { printf("End of Record
(%d)/n", cnt); } else { print $0; } }'


layout_a | sed
'/^Record/{N;N;N;s//n//g;}' | sed 's/^/(Record (.*)/).*input_type /(.*/)$//1
"/2"/;s/^F /(.*/) /(.*/)$/  

"/1" = "/2"/;/^#/d' > layout b

判断
CDR

header

trailer
。如果是
header
,即该行内容为
”RECORD”
,计数器加一,且输出
”Record (?)”
到下一步;如果是
trailer
,即该行内容为
”.”
,输出
”End of Record (?)”
到下一步;否则,不作修改输出到下一步。

2.   


awk 'BEGIN { cnt=0; } { if ( $0 == "RECORD" ) { cnt++;
printf("Record (%d)/n", cnt); } else if ( $0 == "." ) {
printf("End of Record (%d)/n", cnt); } else { print $0; } }' layout_a
|

sed
'/^Record/{N;N;N;s//n//g;}'


| sed 's/^/(Record (.*)/).*input_type /(.*/)$//1
"/2"/;s/^F /(.*/) /(.*/)$/  

"/1" = "/2"/;/^#/d' > layout b

遇到
header
,合并后续三行。因为第四行保留了该
CDR

Record type

3.   


awk 'BEGIN { cnt=0; } { if ( $0 == "RECORD" ) { cnt++;
printf("Record (%d)/n", cnt); } else if ( $0 == "." ) {
printf("End of Record (%d)/n", cnt); } else { print $0; } }' layout_a
| sed '/^Record/{N;N;N;s//n//g;}' | sed '

s/^/(Record (.*)/).*input_type
/(.*/)$//1 "/2"/


;
s/^F /(.*/) /(.*/)$/  

"/1" = "/2"/;/^#/d' > layout b

从上一步生成的
header
提取合适的内容,形成
B
样式的
header
。注意括号的运用。

4.   


awk 'BEGIN { cnt=0; } { if ( $0 == "RECORD" ) { cnt++;
printf("Record (%d)/n", cnt); } else if ( $0 == "." ) {
printf("End of Record (%d)/n", cnt); } else { print $0; } }' layout_a
| sed '/^Record/{N;N;N;s//n//g;}' | sed 's/^/(Record (.*)/).*input_type
/(.*/)$//1 "/2"/;

s/^F /(.*/) /(.*/)$/  

"/1" = "/2"/;


/^#/d' > layout b

提取各个字段的键和值,并加上双引号,形成
B
样式的字段域。同样注意括号的运用。

5.   


awk 'BEGIN { cnt=0; } { if ( $0 == "RECORD" ) { cnt++;
printf("Record (%d)/n", cnt); } else if ( $0 == "." ) {
printf("End of Record (%d)/n", cnt); } else { print $0; } }' layout_a
| sed '/^Record/{N;N;N;s//n//g;}' | sed 's/^/(Record (.*)/).*input_type
/(.*/)$//1 "/2"/;s/^F /(.*/) /(.*/)$/  
"/1" = "/2"/;

/^#/d

' > layout b

删除剩余的注释行。

 

 

抱歉!评论已关闭.