linux shell笔记之awk1

一 分隔符
1.单个分隔符(例将11:22:33字符串取出11 22 33)
   echo 11:22:33 | awk 'BEGIN{FS=":"};{print $1" "$2" "$3;};'

2.定义多个分隔符(例将11:22#33&44字符串取出11 22 33 44)
   echo '11:22#33&44' | awk 'BEGIN{FS="[:#&]"};{print $1" "$2" "$3" "$4;};'

3.定义多个分隔符字符串(例将11:::22##33&&44字符串取出11 22 33 44)
   echo '11:::22##33&&44' | awk 'BEGIN{FS="(:::|##|&&)"};{print $1" "$2" "$3" "$4;};'

4.注意FS使用的是一个正则表达式表示,那么如果有字符串11##22,分隔符为#会被分割成三个字符串,$2是空的,假如#不定长那么使用
   echo '11##22' | awk 'BEGIN{FS="#+"};{print $1" "$2};'

5.那么想分割例3那样不定个:,#,&呢
  echo '11:::22##33&&44' | awk 'BEGIN{FS="(:+|#+|&+)"};{print $1" "$2" "$3" "$4;};'


二 一个统计问题,下面统计所有A B C的总数 输出A:总数 B:总数 ....
A=1
B=20
C=3
C=-5
A=4
A=3
D=8
D=-9
xx=11
xx=22


1.这里使用了关联数组sum[$1]和for循环

   awk 'BEGIN{FS="=";};{sum[$1]+=$2;};END{for(key in sum){print key":"sum[key]}}' test


2.问题:如果上面出现了空行,那么处理空行时需要跳过不处理呢?
   awk 'BEGIN{FS="=";};!/^ *$/{sum[$1]+=$2;};END{for(key in sum){print key":"sum[key]}}' test
   !/^ *$/表示只处理不是空白的行,

3.问题:如果加一行类似D=-9=33那不也有问题,所以要改下只处理两个字段的,对于其他字段的输出出错行,这里还是跳过空白行
   awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
 
4.问题:如果累加的数$2不是数字那么是不是也应该跳过。
   awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){if($2 !~ /^-*[0-9]+$/) next;  sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
   if($2 !~ /^-*[0-9]+$/) next;表示判断整数不匹配则读取一行(next)

5.问题:如果累加的数$2前后有空格怎么办,所以处理时先去除首尾的空格再判断是否数字
    awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){gsub("(^ *)|( *$)","",$2);if($2 !~ /^-*[0-9]+$/) next;  sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
    gsub("(^ *)|( *$)","",$2);表示去除头和尾的空格后存至$2;同样的也可以先对字段1去除首尾空格

你可能感兴趣的:(linux shell笔记之awk1)