shell利器awk介绍与使用小案例

强大的awk指令

1. awk简介

awk 是一个强大的文本分析工具,它是 Linux 中功能强大的数据处理引擎之一,可能这么说非常抽象,awk 可以非常轻松地处理比如每行都是相同格式的文本,比如日志,cvs 格式等等。相对于 grep 的查找,sed 的编辑,awk 在其对数据分析并生成报告时,显得尤为强大。本文,只是简单介绍如何使用awk完成简单的日常任务需求。

2. awk特性
  • 语句格式
    # 统配模式
    awk [options] 'script' file
    

    options 这个表示一些可选的参数选项,script 表示 awk 的可执行脚本代码(一般被{} 花括号包围),这个是必须的。file 这个表示 awk 需要处理的文件,注意需要是纯文本文件(意味着 awk 能够处理)。

    # 传统模式
    awk [options] 'BEGIN{statement} {statement} END{statement}' file
    

    BEGIN: 在脚本代码段前面使用 BEGIN 关键字时,它会在开始读取一个文件之前,运行一次 BEGIN 关键字后面的脚本代码段, BEGIN 中的脚本代码段只会执行一次,执行完之后 awk 程序就会退出。
    END: awk 的 END 指令和 BEGIN 恰好相反,在 awk 读取并且处理完文件的所有内容行之后,才会执行 END 后面的脚本代码段。

  • 内置变量
    awk中,常见和使用最为频繁的内置变量都在下面列举了出来:
    1)NR: 表示文件中的行号,表示当前是第几行。
    2)NF: 表示文件中的当前行被分割的列数,可以理解为 MySQL 数据表里面每一条记录有多少个字段,所以 NF就表示最后一个字段,(NF-1) 就表示倒数第二个字段。
    3)FS: 表示 awk 的输入分隔符,默认分隔符为空格和制表符,可以对其进行自定义设置。
    4)OFS: 表示 awk 的输出分隔符,默认空格,也可以对其进行自定义设置。
    5)FILENAME: 表示当前文件的文件名称,如果同时处理多个文件,它也表示当前文件名称。
    6)RS: 行分隔符,用于分割行,默认换行符
    7)ORS: 输出记录的分隔符,默认换行符
    8)$符取值: $0 表示当前行中的数据。\$1,$2,$3...表示当前行中的第一列,第二列数据,第三列数据…
  • 内置函数
    awk 还提供了一些内置函数,在 awk 的 script 中编写脚本代码的时候,可以直接进行调用。比如:
    • toupper() 用于将字符转为大写
    • tolower() 将字符转为小写
    • length() 长度
    • substr() 子字符串
    • sin() 正弦
    • cos() 余弦
    • sqrt() 平方根
    • rand() 随机数
  • 运算符
    awk中的常见运算符有:

    赋值: =
    算术:+ - * / %
    比较:< <= == != > >= ~ !~~ 表示正则
    逻辑:&& || !

3. awk技巧
  • AWK使用的RE为ERE
  • 如果在BEGIN中设置了OFS, 只有$0有改动OFS才能生效
  • printf与print的区别: printf不自动打印换行符, print则自动打印
  • gsub的返回值并不是替换后的字符串,而是返回替换的次数
  • 字符串常量一定在用” “包围起来,否则当作变量使用, 如$1==“ipaddress”
  • AWK 的 for 循环为C-Style,即为for(),区别于shell中的for i in …
  • AWK中可以使用多个分隔符,要封装在方括号里,用’ ‘包围,以防shell对它们进行解释,如awk -F ‘[ :/t]’,使用空格,冒号,tab作为分隔符
  • next语句:从输入文件中取得下一个输入行,在AWK命令表顶部重新执行命令,一般用于跳过一些特殊的行
  • awk 匹配多个条件:awk ‘/kobe/ && /james/’,这会匹配同时有kobe和james的行
  • FS的默认值是[ /t/n]+, OFS的默认值为空格,RS,ORS的默认值都是换行
  • exit语句:终止AWK程序,但不跳过END语句
  • {s1;s2;s3;…}中多个语句用分号隔开if; else if; else
  • print后不带任何参数时,相当于print $0,将会打印整行记录

运用awk

1. if,for语句

在使用 awk 读取文件或者文件,或者文本的时候,我们需要在遍历每一列,并将符合要求的列中的数据进行输出。那么我们就需要使用到 for 语句与 if 语句。具体语句用法同 shell 有区别。

  • for循环写法:
    #{}中用分号分隔多个动作
    for(i=1;i<=NF;i++){action1; action2; ..} 
    #for后接一个if结构
    for(i=1;i<=NF;i++) if; else if;else
    #简单的循环打印
    for(i=1;i<=NF;i++) printf "for add"
    
  • if判断写法:
    #else if部分可以没有
    if($1 ~ /reg/){action1}; else if($1 ~ /reg2/){action2}; else{action3}
    #多个条件用”&&”,”||”表示
    if($1 ~ /reg/ && $2 ~ /reg2/){action}
    if($1 ~ /reg/ || NR >= 5){action}
    
2. 小案例

开始小案例的演示工作之前,我们需要准备份文本数据,方便指令要操作完成小案例。样例数据(sample_data.txt):

this is sample data
i love shell program
2020 8 14 16 29
apple banana mango orange
so happy today

有了样本数据,那么我们就可以开始操作了,由于篇幅有限,只做个别演示。

  • 读取文本中的每一行数据,并显示行号。
    awk '{print NR "\t" $0}' sample_data.txt
    
    在这里插入图片描述
  • 输出每一行中的第1,2,4列。
    awk '{print NR "\t" $1 " " $2 " "$4}' sample_data.txt
    
    在这里插入图片描述
  • 第3行,将它格式化为日期,输出形式:202-08-16。
    awk ' NR == 3 {$2='0'$2; print  $1 "-" $2 "-"$4}' sample_data.txt
    
    在这里插入图片描述
  • 尝试处理文本,组合输出:i love eat apple的文本。
    awk 'BEGIN{res="";} {if(NR == 2){res=$1" "$2;}else if(NR == 4){res=res" eat "$1;}} END{print res;}' sample_data.txt
    
    在这里插入图片描述
    有关 awk 的操作太多了,对于具体的需求,就需要具体使用了。关于 awk 的更多新技能,那就需要在使用的过程中慢慢探索咯。

编码实践是最有效,最高效的学习技能!
希望我们可以一起学习,一起编码,一起成长进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值