awk 中使用外部shell变量
选项-v可以实现使用外部变量。
如:A=44echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’
,说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。如果有多个变量需要赋值,就需要多个-v选项。
awk 合并一个文件
需求:把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下:
cat 1.txt
1 aa
2 bb
3 ee
4 ss
cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de
合并后的结果为:
1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de
参考:awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' 1.txt 2.txt
解释:NR表示读取的行数, FNR表示读取的当前行数,大家可以运行这个命令 awk ‘{print NR,FNR}’ 1.txt 2.txt,比较NR和FNR。所以其实NR==FNR 就表示读取1.txt的时候。同理NR>FNR表示读取2.txt的时候。数组a其实就相当于一个map。
也可以用paste命令:paste 1.txt 2.txt
。想在两个文件连接处用一个指定的字符连接,还可以用-d来指定:paste -d '+' 1.txt 2.txt
。
把一个文件多行连接成一行
参考:awk '{printf("%s ",$0)}' file
%s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有
也可以用其他命令:
cat file |xargs
a=
cat file;echo $a
awk中gsub函数的使用
awk 'gsub(/www/,"abc")' /etc/passwd #passwd文件中把所有www替换为abc
awk -F ':' 'gsub(/www/,"abc",$1) {print $0}' /etc/passwd #替换$1中的www为abc
awk 截取指定多个域为一行
用awk指定分隔符把文本分为若干段。如何把相同段的内容弄到一行?以/etc/passwd为例,该文件以”:”作为分隔符,分为了7段。
for i in `seq 1 7`
do
awk -F ':' -v a=$i '{printf $a " "}' /etc/passwd
echo
done
过滤两个或多个关键词
grep -E '123|abc' filename #找出文件(filename)中包含123或者包含abc的行
egrep '123|abc' filename #用egrep同样可以实现
awk '/123|abc/' filename #awk 的实现方式
用awk生成结构文件
需求:用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行:
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
参考:awk 'BEGIN{for(i=1;i<=5000000;i++)printf("%d,%d,%00010d,%00010d,%00010d,%00010d,%00010d,%00010d,%d\n",i,i,i,i,i,i,i,i,strftime("%Y%m%d%H%M"))}'
awk语法许多与C语言是一致的,上面数据格式定义、控制语句都可以参考C。
awk用print打印单引号
比较绕,不用死记硬背,以后用的时候,调试几次就出来了。
awk 'BEGIN{print "a'"'"'s"}' #不用脱义,就多写几个单引号、双引号
awk 'BEGIN{print "a'\''s"}' #用脱义,脱义的是单引号
awk 'BEGIN{print "a\"s"}' #用脱义,脱义的是双引号