awk函数+数组+多文件处理

来源:互联网 发布:淘宝交易收多少手续费 编辑:程序博客网 时间:2024/05/16 15:31

对AWK常用的使用进行总结

1.去重复
awk '!a[$0]++' 1.txt
1.txt
1
2
5
2
2

2.统计计算
awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}' 1.txt
1.txt
a 1
b 2
a 5
c 2
b 2

3.截取替换函数
截取函数 substr(a,b,c) a截取的列,b开始截取的位置,c截取的个数
awk '{print substr($0,6,2)}' 1.txt         ===>34
awk '{print substr($0,6)}' 1.txt           ===>34562541
1.txt
0731-34562541

替换gsub,gensub
gensub(a,b,c,d) a:匹配的字符,b替换的字符,c替换的位置(如1,2,g),d替换的列
awk '{print gensub(/.*-/,"abc",1,$0)}' 1.txt        ===>abc34562541
awk '{print gensub(/3/,"C",1,$0)}'     1.txt        ===>07C1-34562541
awk '{print gensub(/3/,"C","g",$0)}'   1.txt        ===>07C1-C4562541
1.txt
0731-34562541

sub/gsub(支持正则)  gsub(a,b,c) a:匹配的字符,b替换的字符,c替换的列
gsub返回的是替换的次数
awk '{print gsub(/3/,"C",$0)}' 1.txt        ===>2
awk 'gsub(/3/,"C",$0)' 1.txt               ===>07C1-C4562541
1.txt
0731-34562541


4.多文件处理,
4.1
awk -F' ' '{getline line<"1.txt" ;n=gensub(/.* /,"",1,line); print $1,$2-n}' 2.txt  
1.txt
1319,[23级]傀儡 358
1320,[23级]傀儡 635
2.txt
1319,[23级]傀儡) 370
1320,[23级]傀儡) 657

awk -F' ' '{getline line;n=gensub(/.* /,"",1,line); print $1,$2-n}' test.txt  //把下一列的值减去上一列的值
test.txt
1319,[23级]傀儡 358
1319,[23级]傀儡) 370


4.2 awk '' file1 file2 文件是一个一个的读 
NR是值两个文件的连续行数  FNR是各自的行数
cat file1:
0011AAA 200.00 20050321
0012BBB 300.00 20050621
0013DDD 400.00 20050622
0014FFF 500.00 20050401

cat file2:
I0011  11111
I0012  22222
I0014  55555
I0013  66666

比较 file1的1-4字符 和 file2的2-5 字符,如果相同,将file2 的第二列 与 file1 合并

0011AAA 200.00 20050321 11111
0012BBB 300.00 20050621 22222
0013DDD 400.00 20050622 66666
0014FFF 500.00 20050401 55555


 awk 'NR==FNR{a[substr($1,2)]=$2} NR>FNR{print $0,a[substr($1,1,4)]}' 2.txt 1.txt 
awk  'NR==FNR{a[substr($1,2,5)]=$2}NR>FNR&&a[b=substr($1,1,4)]{print $0, a[b]}' file2 file1
awk  'NR==FNR{a[substr($1,2,5)]=$2}NR>FNR&&b=a[substr($1,1,4)]{print $0, b}' file2 file1

NR==FNR处理的是file2文件,NR>FNR处理的是file1文件

4.3
cat  file1
    23  中西
    98  红
    34  西瓜
    53  巴巴 

 cat  file2
    巴巴    c
    红      b
    西瓜    d
    中西    f
变成

    23  f
    98  b
    34  d
    53  c
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $1,a[$2]}' file2 file1
awk 'NR==FNR{a[$2]=$1}NR!=FNR{$1=a[$1];print}' file1 file2

4.4
文件一:a
10/05766798607,11/20050325191329,29/0.1,14/05766798607
10/05767158557,11/20050325191329,29/0.08,14/05767158557

文件二:b
05766798607
05766798608
05766798609
通过文件一和文件二对比,导出这样的文件出来.
10/05766798607,11/20050325191329,29/0.1,14/05766798607

grep -f b a

awk -F'/' 'NR==FNR{a[$1]=$1} NR>FNR&&a[$5]{print $0}' 2 1
awk -F'[/,]' 'NR==FNR{a[$1]=$1}NR>FNR&&($2 in a){print $0}' b a
awk -F'[/,]' 'NR==FNR{a[$1]=$1}NR>FNR{for (i in a) { if(i==$2) print $0}}' b a

tips:

在awk中,如果调用next,那么next之后的命令就都不执行了。此行文本的处理到此结束,开始读取下一条记录并操作。
    zoer@ubuntu:~$ cat data   
    1000  
    naughty 500  
    cc 400  
    zoer 100  
    zoer@ubuntu:~$ awk '{if(NR==1){next} print $1,$2}' data   
    naughty 500  
    cc 400  
    zoer 100

与next相似,getline也是读取下一行数据。但是与next不同的是,next读取下一行之后,把控制权交给了awk脚本的顶部。但是getline却没有改变脚本的控制,读取下一行之后,继续运行当前的awk脚本。getline执行之后,会覆盖$0的内容。
   zoer@ubuntu:~$ cat data   
    name naughty  
    25 shandong  
    age 14  
    hah,here is test  
    zoer@ubuntu:~$ cat d  
    $1=="name"{print $0;getline;print $0;}  
    $1=="age"{print $0}  
    zoer@ubuntu:~$ awk -f d data   
    name naughty  
    25 shandong  
    age 14 

 

QUOTE:
           getline从整体上来说,应这么理解它的用法:
            当其左右重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量 
            var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到
            的返回结果是隔行的。
            当其左右重定向符 | 或 < 时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被
            awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。




FROM: http://www.cnblogs.com/belid/archive/2013/05/22/3093264.html

0 0
原创粉丝点击