awk一点心得
博客园awk高手众多;在这里是个人对awk的学习一点心得;同时也是awk的精妙之处;在此若有错误请大家指正,一起来完善!
- awk如何引入变量?有两种方法
1 awk -v var=$VAR '{code}' 2 awk '{print "'$VAR'"}'
例如测试:
1 [li0924@localhost awk]$ a=li0924 2 [li0924@localhost awk]$ echo fef| awk -v var=$a '{print var}' 3 li0924 4 [li0924@localhost awk]$ echo fef | awk '{print "'$a'"}' 5 li0924
2. 三目表达式(expr?values1:values2)
就是类似于C语言中的三目表达式:
例子用法暂时可以查考awk--round函数---http://www.cnblogs.com/lottu/archive/2013/06/10/3131400.html
3. 说道awk的精妙之处;不得不提数组
awk的数组是关联数组;下标可是数字和字符串;无需对数组名和元素提前声明;也不需指定元素的个数;所以awk的数组使用的非常灵活;这个在我们之后《awk案例系列》会用到很多;
读取数组值
1 #输出的顺序是随机的;但是到了awk4之后的版本这种写法是排好序的 2 for(item in array) 3 { 4 print array[item] 5 } 6 #输出的结果是是排好序的 7 for(i=1;i<=len;i++) 8 { 9 print array[i] 10 }
删除数组或数组元素
delete array; 删除整个数组
delete array[item];删除某个数组元素
4. awk输入命令getline
这个函数我理解很久明白;
getline为awk所提供的输入命令
如果找到一条记录则getline返回1,如果到了文件结束(EOF)则返回0,如果错误则返回-1
A.getline从整体上来说,应这么理解它的用法:
- 当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
- 当其左右有重定向符 | 或 < 时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被 awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:
QUOTE:
awk ‘BEGIN{“cat data.txt”|getline d; print d}’ data2.txt
awk ‘BEGIN{“cat data.txt”|getline; print $0}’ data2.txt $0可以省略
awk ‘BEGIN{getline d < “data.txt”; print d}’ data2.txt
awk ‘BEGIN{getline < “data.txt”; print $0}’ data2.txt
技巧1:取偶数行;取奇数行
[li0924@localhost awk]$ seq 10 | awk '{getline; print}' 2 4 6 8 10 [li0924@localhost awk]$ seq 10 | awk '{getline d; print}' 1 3 5 7 9
技巧2:两两互换(奇/偶互换)
[li0924@localhost ~]$ seq 10 | awk '{if(getline d) print d;print}' 2 1 4 3 6 5 8 7 10 9
当然你取奇数行/偶数行方法确实很多;不一定说要用getline函数;你可以是用NR%2这样可以取得奇数行;NR%2==0这样可以取到偶数行!在此就不累赘了!
5. 当我们想以固定的长度来分割列时;这时候需要使用到内置变量FIELDWIDTHS;
[li0924@localhost ~]$ echo "123456789" | awk 'BEGIN{FIELDWIDTHS="2 3 5"}{print $3,$2,$1}' 6789 345 12
$1的长度是2;那么它就是12;$2的长度是3;那么不它就是345;输出的$3;就是6之后面的;
6. OFS为什么有时候它不起作用呢:
例如需要把输出分隔符改为“|”
[li0924@localhost awk]$ cat a.txt WINGS 1000 4000 3 3/20_505 WINGS 5000 6000 8 8/20_505 SANLY 2000 4000 9 9/20_505 TINAG 8000 10000 11 11/20_505 [li0924@localhost awk]$ awk 'BEGIN{OFS="|"}{print}' a.txt WINGS 1000 4000 3 3/20_505 WINGS 5000 6000 8 8/20_505 SANLY 2000 4000 9 9/20_505 TINAG 8000 10000 11 11/20_505
由上我们可以看出OFS并没有生效!那要怎么样使它生效呢?这里我们需要“欺骗”下文件;对文件我们做了什么!
[li0924@localhost awk]$ awk 'BEGIN{OFS="|"}{$1=$1;print}' a.txt WINGS|1000|4000|3|3/20_505 WINGS|5000|6000|8|8/20_505 SANLY|2000|4000|9|9/20_505 TINAG|8000|10000|11|11/20_505
在此你可以把"$1=$1";换成$NF=$NF或$NF+=0都可以!你们可以测试下!
7. awk为假的情况?这个比较重要了;在以后的<awk案例系列>用到比较多!
- 数字0;
- 空字符串;
- 未定义的值;
8. 去重;这个应该放到数组那边的;
awk '!a[$0]++' inputfile
【解析】:a[$0]开始是未定义的;所以是0;但是前面的!;表示该值是非0值;表达式是OK的;但是后面随着a[$0]++;就反之
9. 去除空行
awk 'NF' inputfile
【解析】空行的NF是为0的;NF表示这行有多少个域;而空行是为0;
这个后续在补充。。。

浙公网安备 33010602011771号