awk语法与文本应用处理

转自:http://blog.csdn.net/tianmohust/article/details/6970271

awk命令的一般形式:
awk 'BEGIN    {actions}
     pattern1 {actions}
     pattern2 {actions}
...
     patternN {actions} 
     END      {actions}'  input-filename
其中,BEGIN{actions} 和 END {actions}是可选的。

awk的执行过程如下:
1,如果存在BEGIN,awk首先执行它指定的actions。
2,awk从输入中读取一行,称为一条输入记录。
3,awk将读入的记录分割成个字段,并将第一个字段放入变量$1中,第二个放入变量$2中,依次类推。$0表示整条记录;字段分隔符可以通过选项-F指定,否则使用默认的分隔符。
4,把当前输入记录依次与每一个语句中pattern比较;如果相匹配,就执行相应的actions;如果不匹配,就跳过相应的actions,直到完成所有的语句。
5,当一条输入记录处理完毕后,awk读取下一行,重复上面的处理过程,直到所有输入全部处理完毕。
6,如果输入是文件列表,awk将按顺序处理列表中的每个文件。
7,awk处理完所有的输入后,若存在END,则执行相应的actions。

awk常用的内置变量
变量            说明
NF               当前记录中的字段数
NR              当前记录数
FS               字段分隔符(默认是一个空格)
RS              记录分隔符(默认是一个换行符)
OFS             输出字段分隔符(默认是一个空格)
ORS             输出字段分隔符(默认是一个换行符)
ORSIGNORECASE   如果是真,则进行忽略大小写的匹配

 

awk使用实例:

# 使用awk打印字符串
# awk 'BEGIN { print "hello" }'
#hello

# awk 'BEGIN { print 1.05+2e/10.5+2.0**3-3.14 }'
 
# cat test.txt

#显示输入文件的内容
# awk '{ print }' test.txt

#使用正则表达式匹配行,{actions}省略时表示{print}
# awk '/F[12].*/' test.txt

#使用正则表达式匹配行,并打印匹配的第一和第三列(域或字段)
# awk '/F[12].*/ { print $1,$3 }' test.txt

#更改字段分隔符为!,执行上面的操作
# awk  -F\!  '/F[12].*/ { print $1,$3 }' test.txt

#使用空格或!作为字段的分隔符(正则表达式[ !])
# awk  -F '[ !]'  '/F[12].*/ { print $1,$3 }' test.txt

#使用awk内置的取字串函数提取输入文件中的手机号
# awk  -F '[ !]'  ' { print substr($3,6) }' test.txt

#使用关系表达式书写模式,打印所奇数行
# awk 'NR % 2 == 1' test.txt

#使用关系式书写模式,打印所有奇数行的第1和第3字段
# awk 'NR % 2 == 1 { print $1,$3 }' test.txt

#打印输入文件的总行数,类似于 wc -l test.txt
# awk 'END {print NR}' test.txt
# awk '{ print NR }' test.txt //从1到最后一行

#为每一记录前面添加行号,类似于 wc -n test.txt
# awk '{ print NR,$0 }' test.txt

#为每一记录前面添加行号,并使用制表符作为行号和记录的间隔符
# awk '{ print NR "\t" $0 }' test.txt

#为每行前面加上指定的字符串,并且输入到tmpnum.txt

# awk '{print "tianmo:" $0}' num.txt > tmpnum.txt

#把当前目录下面后缀名为.txt的文件,添加前缀,并且输入到tmpnum.txt

# awk '{print "tianmo:" $0}' *.txt >  tmpnum.txt

注意以下命令的灵活应用

#awk  'NR % 2 == 1' a.txt b.txt  > d.txt

#awk  'NR % 2 == 1'  *.txt  > d.txt

#awk '{print "tianmo:  >" $0}'  *.txt >  tmpnum.txt

#awk '{sum += $5}; END {print sum}' num.txt    //求第五个字段的和

另外,在awk语句里面可以根据条件进行数据筛选,一般是跟字段或字段的某些数,字符进行比较,进而再进行具体的操作。
 
下面再给出一些awk和其他命令使用的例子
#提取文件中的手机号
# cat test.txt | awk -F\! '{ print $3 }' | awk '{ print $1 }' | cut -c6-16

#以文件修改顺序生成当前目录下带有时间的文件名
# ls -aldt * --time-style='+%F_%H:%M' | awk '{ print $7 "--" $6 }'

#计算当前目录中所有12月份创建的文件的字节数
# ls -l | awk ' $6 == "Dec" { sum += $5}; END { print sum }'

#显示当前所有的登录用户和其使用的终端
# who | awk '{ print $1 "\t" $2}'

# df -hPT -x tmpfs //文件设备的详细信息

#显示ifconfig -a的输出中以单词开头的行
# ifconfig -a | grep '^\w'

#显示除了lo之外的所有网络接口
# ifconfig -a | grep '^\w' | awk '!/lo/{print $1}'

#匹配inet的行,以分号为字段间隔符打印第二个字段
# ifconfig eth0 | awk -F\: ' /inet/ { print $2}'
# ifconfig eth0 | awk -F\: ' /inet/ { print $2}' | awk '{print $1}'
# ifconfig eth0 | grep 'inet'

#以一个或多个空格 或:作为字段分隔符(正则表达式'  +|:')
# ifconfig eth0 | grep 'inet' | awk -F ' +|:' '{print $4}'

#以一个或多个空格 或 一个或多个:作为字段分隔符(正则表达式'[ :]+')
# ifconfig eth0 | grep 'inet' | awk -F '[ :]+' '{print $4}'

#删除所有名为foo的进程
# kill 'ps ax | grep 'foo' | grep -v 'grep' | awk '{print $4}''

#查看Apache的并发请求数及其TCP连接状态
# FROM : http://blog.s135.com/read.php/269.htm
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
//NF 是当前记录的字段个数, 使用$NF可以实现每个记录的最后一个字段 就和$6一样

 

awk应用于多行编程

1. 应用场景

在 linux 下有时在处理配置文件是,需要对一个文本块进行处理,此时使用 awk 的强大功能。文本块的格式是如下:

[section1]

tag1 = value_a

tag2 = value_b

tag3 = value_c

[section 2]

tag4 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

subtag3 = subtag_value_c

}

[section 3]

tag6 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

}

现在有个需求,需要在[section 2] 这个文本块加入tag5={key=vaule}( 类似于tag4 的格式) 这种形式的属性。当然还需要对其进行修改和删除。下面就是示范使用awk 来进行处理。

1.1. 增加

假设现在要进行添加操作,首先必须要检查tag5 这个文本块是否存在,如果不存在就添加。awk 编程如下:

[python] view plain copy
  1. awk –v TAGVALUE1=vaule_a –v TAGVALUE2=vaule_b  '{  
  2.   if ($0 ~ /^/[section 3/]$)  
  3.     print   "tag5 = {/nsubtag1= " TAGVALUE1 "/nsubtag2= " TAGVALUE2 "/n} "  
  4.   print  #其他保持不变  
  5. }' a.conf   

结果如下:

[root@local~]#cat a.conf ·

[section 2]

tag4 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

subtag3 = subtag_value_c

}

tag5 = {

subtag1 = value_a

subtag2 = value_b

}

[section 3]

tag6 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

1.2. 修改

假设现在要进行修改操作( 把tag5 中的 subtag2 的值修改为 vaule_bb ) ,首先必须要检查tag5 这个文本块是否存在,如果存在就修改。awk 编程如下:

[python] view plain copy
  1. awk –v TAGVALUE2=vaule_bb  '{  
  2.   if ($1== tag5) {  #找到tag5这个文本块  
  3.      do{  
  4.        getline;   #得到$0  
  5.        if ($1 == "subtag2"){  
  6.          print "subtag2 = " TAGVALUE2  
  7.          continue  
  8.        }  
  9.        print $0   #其他保持不变  
  10.     }while($1 != "}")  
  11.   }  
  12.   print $0  # 其他保持不变  
  13. } ' a.conf  

结果如下:

[section 2]

tag4 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

subtag3 = subtag_value_c

}

tag5 = {

subtag1 = value_a

subtag2 = value_bb

}

[section 3]

tag6 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

}

1.3. 删除

假设现在要进行删除操作( 把tag5 这个文本块删除 ) ,首先必须要检查tag5 这个文本块是否存在,如果存在就删除。awk 编程如下:

[python] view plain copy
  1. awk  '{  
  2.   if ($1== tag5) {  #找到tag5这个文本块  
  3.      do{  
  4.        getline;   #得到$0  
  5.      }while($1 != "}"#删除该块  
  6.   }  
  7.   else  
  8.     print $0  # 其他保持不变  
  9. }' a.conf  

结果如下:

[section 2]

tag4 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

subtag3 = subtag_value_c

}

[section 3]

tag6 = {

subtag1 = subtag_value_a

subtag2 = subtag_value_b

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值