Linux学习之awk学习之cookbook技巧

awk学习之cookbook技巧.md

#Awk One-Liners Explained, Part 1: File Spacing, Numbering and Calculations

##1.Line Spacing

1.每行后面都加上一个空行

awk '1; { print "" }'       #awk学习之cookbook技巧

awk 程序包含一系列的 parttern-action(模式-动作)的语句。类似这样‘pattern{action}’的结构。
这个例子中包含了2个语句,一个是 “1”,另一个是“{print “” }”,模式和动作都可以省略的其中一个的。
如果模式省略了,默认是对所有的输入内容按行来出来的。如果是动作省略的默认是“{print }”。

注意awk程序是面向行的。awk学习之cookbook技巧

上面的等同于下面这个程序

awk '1 { print } { print "" }'     #awk学习之cookbook技巧

动作只有在模式匹配的情况下才执行。这里例子中的模式是“1”,这个模式总是true,也就是每一行都会匹配,
每一行也都会执行动作的。所以也等价于下面的代码:


awk '{ print } { print "" }'   #awk学习之cookbook技巧

awk的print语句总是会在最后打印一个ORS(output record separator)变量的,这个值模式是换行,
也就是\n #awk学习之cookbook技巧
这里例子中的第一个print语句后面没有接任何参数,所有默认等于print $0,也就是打印整行内容,
$0代表的是整行内容。 #awk学习之cookbook技巧
例子中的第二个print 打印一个空字符串,也是上面都不输出,打上print会在最后加上一个换行,所以呢
这里就打印出来了一个空行了。#awk学习之cookbook技巧

2.另外一个给每行后面加上空行的技巧

awk 'BEGIN { ORS="\n\n" }; 1' #awk学习之cookbook技巧

BEGIN是一个特殊的模式,表示在读取内容之前无条件执行后面的动作。
这个技巧中是在动作语句中对ORS变量重新赋值了,将一个换行变成两个换行了。
后面 的1 等价于 {print} ,这样就达到了每行后面都加上新的空行的目的。

$ awk 'BEGIN { ORS="\n\n" }; 1' /etc/passwd
root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

3.在每个非空的行后面添加空行

awk 'NF { print $0 "\n" }' #awk学习之cookbook技巧

这个技巧用到了awk中的另外一个特殊变量NF(number of fields)。这个表示每行被awk分割为多少个字段,
也就是多少列,默认是安装空格分割的。例如“this is a test”这行会被分割为4个字段。
如果是空行,是不会分割的,也就是NF的值是0。#awk学习之cookbook技巧
这里使用NF作为模式,只有NF值大于0条件才是真,后面的动作才执行。
后面的动作是print $0,也就是打印整行内容,print第二个参数是个换行,也就是后面加个新的空行。

4、在每行后添加两个空行

awk '1; { print "\n" }' #awk学习之cookbook技巧

1是等于{print}的,所以上面的可以等价于下面这个 #awk学习之cookbook技巧

awk '{ print; print "\n" }'  #awk学习之cookbook技巧

首先是打印一整行内容,然后再打印一个换行。 #awk学习之cookbook技巧

##2.Numbering and Calculations

5、为每个文件的内容添加行号

awk '{ print FNR "\t" $0 }' #awk学习之cookbook技巧

这则技巧是在没一行的开头加上FNR(file line number行号)然后是一个\t( tab键),最后是整行内容。
FNR变量记录了当前的行号。FNR会每次重置为0的。

$ awk '{ print FNR "\t" $0 }' ffmpeg.sh  
1	#!/bin/bash #awk学习之cookbook技巧
2	
3	INPUT_FILE="$1"
4	ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
$ 

6、为所有文件的所有行统一添加行号


awk '{ print NR "\t" $0 }'      #awk学习之cookbook技巧

这个和上面的那个例子类似,只是这里使用NR(line number)变量了,这个不会重置为0的。


$ awk '{ print FNR "\t" $0 }' ffmpeg.sh ffmpeg.sh                                                                                                           
1	#!/bin/bash  #awk学习之cookbook技巧
2	
3	INPUT_FILE="$1"
4	ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
1	#!/bin/bash   #awk学习之cookbook技巧
2	
3	INPUT_FILE="$1"
4	ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"






                                                                                                                                                            
$ awk '{ print NR "\t" $0 }' ffmpeg.sh ffmpeg.sh                                                                                                             
1	#!/bin/bash  #awk学习之cookbook技巧
2	
3	INPUT_FILE="$1"
4	ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
5	#!/bin/bash  #awk学习之cookbook技巧
6	
7	INPUT_FILE="$1"
8	ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
$

我们可以看到当作用到2个文件来显示行号的时候 FNR是会在第二个文件重置为0 的。
NR变量则不会重置为0 的。

7、 格式化行号


awk '{ printf("%5d : %s\n", NR, $0) }'  #awk学习之cookbook技巧

这个例子使用到了printf 函数,这个类似bash/c语言中的printf()函数。这个函数是不会在每行结尾追加打印ORS,也就是不会打印换行的。


$ awk '{ printf("%5d : %s\n", NR, $0) }' ffmpeg.sh ffmpeg.sh      #awk学习之cookbook技巧
    1 : #!/bin/bash #awk学习之cookbook技巧
    2 : 
    3 : INPUT_FILE="$1"
    4 : ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
    5 : #!/bin/bash #awk学习之cookbook技巧
    6 : 
    7 : INPUT_FILE="$1"
    8 : ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"


8.非空行前面添加行号

awk 'NF { $0=++a " :" $0 }; { print }' #awk学习之cookbook技巧

awk中是可以使用变量的,当然也可以使用自定义的变量,和bash是类似的,不需要先定义在使用,可以直接使用的。
之前我们用到的那些个变量都是awk自己定义的。#awk学习之cookbook技巧

这个例子怎么理解呢?
首先 这里是2个模式动作语句。第一个是 NF { $0=++a " :" $0 },第二个是{ print }
第一个里面 ++a是定义了一个变量a,这里初始就是0(数字零),而不是什么空或者空字符串。
为啥是数字也是因为这个++操作符是作用到数字上面的。#awk学习之cookbook技巧
然后执行++操作(类似c语言里面的前置++)a第一次执行就会变为1了。
什么时候第一次执行呢也就是第一个不是空行的时候才是首次执行。因为NF模式匹配非空行。上面有个例子讲过。

然后是++a “ :” $0这3个值按照字符串拼接那样拼接起来,然后一起重新复制给变量$0了,$0表示整行内容,
这里就实现了给非空行重新设置行号的目的了。注意拼接字符串不能使用加号,加号只能作用到数字上面。

第一个模式动作语句是不打印内容的。#awk学习之cookbook技巧

然后是第二个模式动作语句,里面只有一个print,默认就是打印$0,默认就是打印整行内容。
这里不管是空行,还是非空行都统统的打印出来,非空行因为是之前在第一个模式动作中重新被
赋值了,这里也就实现了打印非空行行号的目的了。#awk学习之cookbook技巧

同时我们可以看到这个awk程序作用到2个文件的时候,变量a是不会被重置的。#awk学习之cookbook技巧


$ awk 'NF { $0=++a " :" $0 }; { print }' ffmpeg.sh ffmpeg.sh     #awk学习之cookbook技巧
1 :#!/bin/bash #awk学习之cookbook技巧

2 :INPUT_FILE="$1"
3 :ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"
4 :#!/bin/bash #awk学习之cookbook技巧

5 :INPUT_FILE="$1"
6 :ffmpeg -y -i "$INPUT_FILE" -vf drawtext="fontfile=fonts/simsun.ttc: text='欢迎光临 马哥的淘宝店<马哥私房菜> 地址是:shop592330910.taobao.com':fontcolor=red:fontsize=40:box=1:boxcolor=black@0:x=if(eq(mod(t\,3)\,0)\,rand(0\,(w-text_w))\,x):y=h-text_h" -codec:a copy "new.${INPUT_FILE}"


9.计算文件行数(模拟 wc -l 命令)


awk 'END { print NR }'  #awk学习之cookbook技巧

这里又用到了一个特殊的模式END,这个表示所有行处理完,最后在执行这个模式后面的动作。
这个例子就是打印NR的值,也就是最终的行数。 #awk学习之cookbook技巧

$ 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值