从初学awk到现在小有所成,非常感谢CUers的帮助,总结了下自己曾经遇到的问题和犯的错误,供初学者借鉴,因本人非计算机专业,对专业词汇可能有表述不对的地方,还请指正和补充! 1. awk ‘{code}1’ 中的“1”是干什么的? 一个完整的awk语句为:Awk ‘[patten]{action}……’, 其中pattern缺省为1,action缺省为{print}。 那么awk ‘1’完整的写法就是awk ‘1{print}’; 同理,awk ‘{print}’完整的写法也是awk ‘1{print}’。 2. NR和FNR的区别是啥? NR: 当前行记录数。 FNR: 当前文件的行记录数。 当awk处理的文件数超过1时,NR和FNR才会有区别。例如:
3. Awk怎么引入变量? 有两种方法:
<1>: awk -v var=$VAR '{code}'
我推荐使用第一种方法,这样可以避免一些不必要的烦恼。如 4. 为什么OFS不起作用? 先看一个例子:
上面的例子中OFS为什么没有生效呢,原因是OFS指的是输出字段分隔符,所以必须对字段进行操作时OFS才会起作用,正确的方法应该是:
正如Tim大师所讲的,$1=$1这个action,是我们对awk撒的谎,目的就是为了使得OFS生效,除此之外,NF+=0也是常用的方法。参考: 5. 同样的代码,别人运行成功,为什么我运行失败? 这个问题的原因很多,我这里列举两个最常见的,大家可以补充。 <1>: awk版本引起的,如gawk中的一些扩展函数或变量,在nawk中没有,或是不同版本的(g/n)awk也会有差别,这样情况需要重新编写。 <2>: 文本格式的问题,cat-A file查看一下,如果是,dos2unix应该可以解决。 注:书写错误也有可能哦 6. Awk 语句中可以使用{n,m}这样的正则么? 可以,使用方法:gawk -- re-interval ,其它版本使用方法会有所不同,请大家补充 7. BEGIN 和END 到底是怎么一回事? 有时,对于新手可能也会是个问题。简单说下: BEGIN {action} : 读取文本之前进行的操作。要避免类似下面的写法:
如果BEGIN 模块中使用getline函数时,情况会有所不同:
END {action}: 8. print,printf 和sprintf? print:为一般的打印 printf:可以定义打印格式
sprintf:可以完成和printf相同的功能,不同的是sprintf只能输出值,并不能完成打印的功能。 例如:
9. “a==b?c:d” ? 这个是一个if语句的简写,即conditional expression1 ? expression2: expression3;完整写法为: if(a==b) {c} else {d} 10. awk ‘! a[$0]++’ 怎么理解? 这是一个非常经典的去重复项的awk语句,虽然短小,不过涉及到了不少知识点,下面一一解读: <1> :”!” 即非。 <2>:a[$0],以$0为数据下标,建立数组a <3>:a[$0]++,即给数组a赋值,a[$0]+=1 <4> :那么组合起来,awk是怎么执行!a[$0]++的呢?我用一个实际例子来解释:
原来,第一个a[$0]的值为空,所以!a[$0]++是先作判断,结果为1(非空为真,即为1),再作数组赋值a[$0]++。这也就是为什么前面的!a[$0]++并不一定等于后面的!a[$0]。 awk ‘++a[$0]==1’ 和上面的代码作用一样,你理解了么? 11. 如何打印单双引号?
更可靠的的方法如Tim所示: 12. awk 语句中多个{}是怎么执行的? 还是用个例子来说明:
这样可以清楚的看出,awk是一行一行读取文本,然后按照代码的前后顺序执行。但如果action中包含next或exit时,有所不同:
13. FS, OFS, RS, ORS? 最后用图解的方式说明一下这四个变量: |