美文网首页
awk命令的使用(初探)

awk命令的使用(初探)

作者: 一只烟酒僧 | 来源:发表于2020-04-24 11:23 被阅读0次

    参考文章:https://www.cnblogs.com/along21/p/10366886.html#重要!
    参考文章:https://www.runoob.com/w3cnote/awk-work-principle.html#awk的工作原理
    sed和awk的区别:https://www.zhihu.com/question/297858714
    AWK简明教程:https://coolshell.cn/articles/9070.html
    sed官方手册:http://www.gnu.org/software/sed/manual/sed.html
    sed简明教程:https://coolshell.cn/articles/9104.html
    sed命令简介1:http://linux.51yip.com/search/sed
    sed命令简介2:https://man.linuxde.net/sed
    sed命令简介3:https://www.runoob.com/linux/linux-comm-sed.html
    awk内置函数使用说明:https://blog.csdn.net/w36680130/article/details/81029527

    一、概述

    awk是一个文本处理软件,更是一门语言,用于在linux下对文本进行处理。其输入可以是标准输入、文件(多个)或其它程序的输出,通过其高度灵活的文本处理方法,如正则表达式、自定义函数、内置变量、格式化输出等 对文本进行高效处理。本文仅对awk最最基础的原理及应用做总结。

    二、awk的工作原理

    与sed类似,awk本质上也采用了逐行处理的模式,首先awk会先运行一次标识为BEGIN{}的命令,一般是一些预设变量等,之后会将文本逐行读入变量中,通过模式匹配(正则)、函数等方法进行处理,将整个文件全部逐行处理完成之后,再通过表示END{}的命令完成后续操作,最终将结果输出为标准输出。


    awk工作原理

    与sed相比,awk在格式上更复杂,其语法也更规范化,包括了函数、自定义函数、循环、条件、变量等编程语言必备的要素,在学习过程中比sed更难,但功能更强大。

    三、awk的命令模式

    1、命令行的标准模式: awk [options] -v var=value 'BEGIN{action...}pattern{action...}END{action...}' file(s)
    2、接受脚本文件的格式 :awk [options] -f programfile var=value file(s)
    3、命令行的常用模式(简单模式):awk [options] -F 分隔符 ’command‘ file(s)

    四、awk的参数、语法和应用实例

    1、awk的参数

    因为awk是门语言,所以很多功能都是通过语法实现的,参数比较少,常用的几个如下:
    -F fs:fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
    -v var=value:赋值一个用户定义变量,将外部变量传递给awk
    -f scripfile:从脚本文件中读取awk命令
    另注:基本上参数能实现的功能,语法都可以实现,只不过参数比较方便。

    2、awk的语法

    2.1 awk的变量

    awk中可以更改内置变量的值或定义自己的变量,用两种方法,一种是通过-v 参数 如awk -v FS=\n '{}' file 另一种是直接在语句中定义,但要用引号,如 awk '{FS="\n";print FS} file

    2.1.1 awk的内置变量

    FS :输入字段分隔符,默认为空白字符,如FS=":",表示输入行的字段根据冒号分隔为不同列
    OFS :输出字段分隔符,默认为空白字符,如OFS=“:”,表示输出行的字段中间插入冒号再合并分隔输出
    RS :输入记录分隔符,指定输入时的换行符,原换行符仍有效,如 RS=":" ,意思是把输入行中的冒号替换成换行符
    ORS :输出记录分隔符,输出时用指定符号代替换行符。如 ORS=":",意思是把输出的行中的换行符替换成冒号
    NF :字段数量,即统计每行被分割成多少字段, NF可以表示最后一列,(NF-1)可以表示倒数第二列
    NR :行号,后可跟多个文件,第二个文件行号继续从第一个文件最后行号开始
    FNR :各文件分别计数, 行号,后跟一个文件和NR一样,跟多个文件,第二个文件行号从1开始
    FILENAME :当前文件名
    ARGC :命令行参数的个数 ,一般用在BEGIN里面
    ARGV :数组,保存的是命令行所给定的各参数,查看参数 ,同上

    2.1.1.1实例

    实例文件一 :awkdemo

    [root@along ~]# cat awkdemo
    hello:world
    linux:redhat:lalala:hahaha
    along:love:youou
    [root@along ~]# awk -v FS=':' '{print $1,$2}' awkdemo  #FS指定输入分隔符
    hello world
    linux redhat
    along love
    [root@along ~]# awk -v FS=':' -v OFS='---' '{print $1,$2}' awkdemo  #OFS指定输出分隔符
    hello---world
    linux---redhat
    along---love
    [root@along ~]# awk -v RS=':' '{print $1,$2}' awkdemo
    hello
    world linux
    redhat
    lalala
    hahaha along
    love
    you
    [root@along ~]# awk -v FS=':' -v ORS='---' '{print $1,$2}' awkdemo
    hello world---linux redhat---along love---
    [root@along ~]# awk -F: '{print NF}' awkdemo
    2
    4
    3
    [root@along ~]# awk -F: '{print $(NF-1)}' awkdemo  #显示倒数第2列
    hello
    lalala
    love
    [root@along ~]# awk '{print NR}' awkdemo awkdemo1
    1
    2
    3
    4
    5
    [root@along ~]# awk END'{print NR}' awkdemo awkdemo1
    5
    [root@along ~]# awk '{print FNR}' awkdemo awkdemo1
    1
    2
    3
    1
    2
    [root@along ~]# awk '{print FILENAME}' awkdemo
    awkdemo
    awkdemo
    awkdemo
    [root@along ~]# awk 'BEGIN {print ARGC}' awkdemo awkdemo1
    3
    [root@along ~]# awk 'BEGIN {print ARGV[0]}' awkdemo awkdemo1
    awk
    [root@along ~]# awk 'BEGIN {print ARGV[1]}' awkdemo awkdemo1
    awkdemo
    [root@along ~]# awk 'BEGIN {print ARGV[2]}' awkdemo awkdemo1
    awkdemo1
    

    2.1.2自定义变量

    定义方法与上文一样,只不过变量名是用户自己起的。

    2.2prinf 格式化输出

    格式化输出:是指在输出处理结果的时候以用户自定义的某个样式进行输出。

    2.2.1 语法

    awk '{com;printf "FORMAT", item1,item2, ...}' file

    FORMAT指用户想呈现的格式,item指在哪一个位置呈现,因此,format要与item在顺序上一一对应。
    不会自动换行,需要显式给出换行控制符,\n
    常用格式:awk '{prinf "%-10s %-10s %-10s %-10s\n",1,2,3,4}' file
    常用格式说明:输出1-4行,格式为左对齐(-),至少显示10个字符,多于10个继续显示,不足十个空格补齐(%10s),列之间用空格分开,每行末尾加上换行符

    格式符
    %c: 显示字符的ASCII码
    %d, %i: 显示十进制整数
    %e, %E: 显示科学计数法数值
    %f :显示为浮点数,小数 %5.1f,带整数、小数点、整数共5位,小数1位,不够用空格补上
    %g, %G :以科学计数法或浮点形式显示数值
    %s :显示字符串;例:%5s最少5个字符,不够用空格补上,超过5个还继续显示
    %u :无符号整数
    %%: 显示% 自身
    修饰符
    #[.#]:第一个数字控制显示的宽度;第二个# 表示小数点后精度,%5.1f
    -:左对齐(默认右对齐) %-15s
    +:显示数值的正负符号 %+d

    2.2.2 实例

    [root@along ~]# awk -F: '{print $1,$3}' /etc/passwd
    root 0
    bin 1
    ---第一列显示小于20的字符串;第2列显示整数并换行
    [root@along ~]# awk -F: '{printf "%20s---%u\n",$1,$3}' /etc/passwd
                    root---0
                     bin---1
    ---使用-进行左对齐;第2列显示浮点数
    [root@along ~]# awk -F: '{printf "%-20s---%-10.3f\n",$1,$3}' /etc/passwd
    root                ---0.000    
    bin                 ---1.000
    ---使用printf做表格
    [root@along ~]# awk -F: 'BEGIN{printf "username            userid\n-----------------------------\n"}{printf "%-20s|%-10.3f\n",$1,$3}' /etc/passwd
    username            userid
    -----------------------------
    root                |0.000    
    bin                 |1.000
    

    2.3 操作符

    2.3.1 类型

    写在前面:比较重要的操作符为 模式匹配符 ~ 逻辑操作符 函数调用符和条件表达式(类似于R中的ifelse函数)
    算术操作符:
    x+y, x-y, x*y, x/y, x^y, x%y
    -x: 转换为负数
    +x: 转换为数值
    字符串操作符:没有符号的操作符,字符串连接
    赋值操作符:
    =, +=, -=, *=, /=, %=, ^=
    ++, --
    比较操作符:
    ==, !=, >, >=, <, <=
    模式匹配符:~ :左边是否和右边匹配包含 !~ :是否不匹配
    逻辑操作符:与&& ,或|| ,非!
    函数调用: function_name(argu1, argu2, ...)
    条件表达式(三目表达式):selector?if-true-expression:if-false-expression
    注释:先判断selector,如果符合执行 ? 后的操作;否则执行 : 后的操作

    2.3.2 实例

    1、模式匹配符

    ---查询以/dev开头的磁盘信息
    [root@along ~]# df -h |awk -F: '$0 ~ /^\/dev/'
    /dev/mapper/cl-root   17G  7.3G  9.7G  43% /
    /dev/sda1           1014M  121M  894M  12% /boot
    ---只显示磁盘使用状况和磁盘名
    [root@along ~]# df -h |awk '$0 ~ /^\/dev/{print $(NF-1)"---"$1}'
    43%---/dev/mapper/cl-root
    12%---/dev/sda1
    ---查找磁盘大于40%的
    [root@along ~]# df -h |awk '$0 ~ /^\/dev/{print $(NF-1)"---"$1}' |awk -F% '$1 > 40'
    43%---/dev/mapper/cl-root
    

    2、逻辑操作符

    [root@along ~]# awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd
    root 0
    bin 1
    [root@along ~]# awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
    root
    [root@along ~]# awk -F: '!($3==0) {print $1}' /etc/passwd
    bin
    [root@along ~]# awk -F: '!($0 ~ /bash$/) {print $1,$3}' /etc/passwd
    bin 1
    daemon 2
    

    3、条件表达式

    [root@along ~]# awk -F: '{$3 >= 1000?usertype="common user":usertype="sysadmin user";print usertype,$1,$3}' /etc/passwd
    sysadmin user root 0
    common user along 1000
    

    2.4 模式匹配操作(重点!!)

    重点:awk的模式匹配操作与sed类似,基本代码逻辑都是 address{comd} 格式
    (1)如果未指定:空模式,匹配每一行
    (2)/regular expression/ :仅处理能够模式匹配到的行,正则,需要用/ / 括起来
    (3)relational expression:关系表达式,结果为“真”才会被处理
    真:结果为非0值,非空字符串
    假:结果为空字符串或0值
    (4)line ranges:行范围
    startline(起始行),endline(结束行):/pat1/,/pat2/ 不支持直接给出数字,可以有多段,中间可以有间隔
    (5)BEGIN/END 模式
    BEGIN{}: 仅在开始处理文件中的文本之前执行一次
      END{} :仅在文本处理完成之后执行
    实例如下

    [root@along ~]# awk -F: '{print $1}' awkdemo
    hello
    linux
    along
    [root@along ~]# awk -F: '/along/{print $1}' awkdemo
    along
    [root@along ~]# awk -F: '1{print $1}' awkdemo
    hello
    linux
    along
    [root@along ~]# awk -F: '0{print $1}' awkdemo
    [root@along ~]# awk -F: '/^h/,/^a/{print $1}' awkdemo
    hello
    linux
    along
    [root@along ~]# awk -F: 'BEGIN{print "第一列"}{print $1} END{print "结束"}' awkdemo
    第一列
    hello
    linux
    along
    结束
    

    2.5 awk的高阶使用

    2.5.1 条件语句

    if(condition){statement;…}[else statement] 双分支
    if(condition1){statement1}else if(condition2){statement2}else{statement3} 多分支

    2.5.2 for循环

    for(expr1;expr2;expr3) {statement;…}
    for(var in array) {for-body}

    2.5.3 字符串处理(重点!!语法上与R中对应的函数一样)

    length([s]) :返回指定字符串的长度
    sub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并将第一个匹配的内容替换为s
    gsub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并全部替换为s 所表示的内容
    plit(s,array,[r]) :以r 为分隔符,切割字符串s ,并将切割后的结果保存至array 所表示的数组中,第一个索引值为1, 第二个索引值为2,…

    2.5.4 其它高阶(以后填坑)

    awk其它循环模式
    awk自定义函数
    awk数组
    awk中调用shell 命令

    相关文章

      网友评论

          本文标题:awk命令的使用(初探)

          本文链接:https://www.haomeiwen.com/subject/rpyxwhtx.html