• awk入门教程


    awk

    awk 不仅是一个数据处理工具,而且是一门解释性的编程语言。它提供了十分强大的功能:支持流程控制、数学运算符,内置函数等。但是大多数时候 awk 只表现为一个命令,我们可以使用这个命令对文本数据进行格式化处理。

    任务众多可以使用 awk 完成。以下只是其中的几个:

    • 文本处理
    • 产生格式化文本报告
    • 执行算术运算
    • 执行字符串操作等等

    如果想深入学习 awk,可以到 官网 学习,如果只是简单学会使用,读完这篇文章即可。


    一、基本用法

    awk 的用法基本是下面的形式:

    # 格式
    $ awk [选项] '[条件] {动作}' 文件名
    
    # 示例1
    $ awk '/usr/ {print $0}' demo.txt
    # 示例2 awk 使用选项 -F 指定分割符号为 ":",不指定分割符默认为 空格
    $ awk -F : '/usr/ {print $0}' demo.txt 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对于 awk '/usr/ {print $0}' demo.txt ,它类似 shellwhile 循环:

    $ while read line;do echo "$line";done <demo.txt
    
    • 1

    awk 后面接两个单引号并加上大括号 {} 来设定想要对数据进行的处理动作。当然 awk 可以处理后续接的文件,也可以读取来自前个指令的标准输出。print命令前面是一个正则表达式,只输出包含usr的行。

    awk 隐藏了读取每一行的 while 循环,它会自动读取每一行,其中的 {print $0} 对应于 Shellwhile 循环体 echo "$line" 部分。

    实际上,awk 默认会根据 空格制表符,将每一行分成若干字段,依次用 $1$2$3 代表第一个字段、第二个字段、第三个字段等等。

    $ echo 'this is a test' | awk '{print $0}'
    this is a test
    $ echo 'this is a test' | awk '{print $1}'
    this
    $ echo 'this is a test' | awk '{print $2}'
    is
    $ echo 'this is a test' | awk '{print $3}'
    a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    二、awk 运行方式

    1. 命令行方式

    # 格式
    $ awk [选项] '[条件] {动作}' 文件名
    
    # 示例
    $ awk '{print $0}' demo.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 管道方式

    # 格式
    $ cat [文件名] | awk [动作]
    
    # 示例
    $ cat demo.txt | awk '{print $3}'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:前面的命令不一定是 cat 命令,只需要是输出就行。比如 ls 命令


    3. 脚本

    创建 .awk 后缀的脚本,并添加 chmod +x [文件名] 可执行权限

    # 示例
    $ touch test.awk
    $ chmod +x test.awk
    $ vim test.awk
    
    • 1
    • 2
    • 3
    • 4

    添加以下内容

    #!/usr/bin/awk -f
    
    # 使用BEGIN指定字符来设定"FS"内置变量,不能用"-F"来指定了
    BEGIN { FS=":" }
    
    # 这里可以写命令行方式引号内的语句,即正则+命名
    {
        print $1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行

    $ ./test.awk
    -> 111:222:333
    111
    -> 222:333
    222
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、 内置变量

    awk 内置了很多变量,比如我们前面举例的 $ + 数字 表示某个字段,除此之外还提供一些其他的变量。

    为了方便演示,我们新建一个 demo.txt ,如下所示:

    $ vim demo.txt
    1.1 2 3 A B C
    4.1 5 6 D E F
    7.1 8 9 H I J
    
    • 1
    • 2
    • 3
    • 4

    1. NF

    NF 代表当前行有多少个字段,$NF 就代表最后一个字段

    $ cat demo.txt|awk '{print NF "\t" $NF}'
    6	C
    6	F
    6	J
    
    • 1
    • 2
    • 3
    • 4

    上面代码中,我们使用了转义

    同理,$(NF-1) 就代表倒数第二个字段

    $ cat demo.txt| awk '{print NF-1 "\t" $(NF-1)}'
    5	B
    5	E
    5	I
    
    • 1
    • 2
    • 3
    • 4

    2. NR

    变量 NR 表示当前处理的是第几行,即表示当前行的行号。

    $ awk  -F ':' '{print NR ") " $1}' demo.txt
    1) 1.1 2 3 A B C
    2) 4.1 5 6 D E F
    3) 7.1 8 9 H I J
    
    • 1
    • 2
    • 3
    • 4

    3. FS

    此变量表示输入的数据域之间的分隔符,其默认值是空格。 我们可以使用 -F 命令行选项改变它的默认值。

    $ awk 'BEGIN {print "FS = " FS}'
    FS =  
    
    • 1
    • 2

    其他

    • awk的其他内置变量如下:

    FILENAME:当前文件名。

    RS:它表示(输入)记录分隔符以及它的默认值是换行。

    FNR:它类似于 NR,但相对于当前文件。这是当 awk 工作在多个文件非常有用。 FNR 的值将重置使用新的

    文件。

    ORS:输出记录换行符。一般我们肯定会理所当然的认为,换行符肯定就是\n 。但事实上,我们可以通过

    ORS 变量指定相应的换行符。

    ARGC:命令行参数的个数。

    ARGV:命令后参数的数组。可以逐个打印,比如 ARGV[0],默认 ARGV[0] 为 “awk” 。


    四、函数

    awk 内置了许多函数,可以直接使用。

    • 常用的内置函数如下:
    toupper():用于将字符转为大写。
    tolower():字符转为小写。
    length():	返回字符串长度。
    substr():	返回子字符串。
    sin():		正弦。
    cos():		余弦。
    sqrt():		平方根。
    rand():		随机数。返回一个随机数N,在0和1之间,使得0<= N <1。
    int():		整数。这个函数截断数字为整数值。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例如下:

    $ awk  -F ':' '{print int($1)}' demo.txt
    1
    4
    7
    
    • 1
    • 2
    • 3
    • 4

    五、awk 的模式(条件)

    为了方便演示,我们新增了一个 demo1.txt。

    $ vim demo1.txt
    /usr/root
    mysql
    /usr/daemon
    /usr/bin
    sys
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    前面我们说到 awk 的[基本用法](# 一、基本用法),如下所示:

    # 格式
    $ awk [选项] '[条件] {动作}' 文件名
    
    • 1
    • 2

    条件(Pattern),即为 模式,就是花括号前面的那一串字符串,如示例中的 /usr/Pattern 由于有方括号(表示该参数可忽略)。

    条件(Pattern)/模式 的两种类型

    • 数学及逻辑运算符,包括:<===>=!=&&!
    • 正则表达式匹配,只有两个:~ (正则匹配返回true)、!~(正则不匹配返回true)。

    其实正则表达式的 ~!~ 这两个符号并不是必须的,当不使用这两个符号时,表示对整行进行匹配,否则可以对指定列进行 匹配,另外正则表达式必须写在两个斜杠里**(/这是正则表达式/ )**

    # 示例
    $ awk -F ':' '/usr/ {print $1}' demo1.txt
    /usr/root
    /usr/daemon
    /usr/bin
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上面代码中,print 命令前面是一个正则表达式,只输出包含 usr 的行。

    # 示例1 
    $ awk -F ':' 'NR % 2 == 0 {print $1}' demo1.txt
    mysql
    /usr/bin
    
    • 1
    • 2
    • 3
    • 4

    上面代码中,print 命令前面是数学逻辑条件,只输出偶数行

    # 示例2
    $ awk -F ':' '$1 == "/usr/root" {print $1}' demo1.txt
    /usr/root
    # 示例3
    $ awk -F ':' '$1 == "mysql" || $1 == "sys" {print $1}' demo1.txt
    mysql
    sys
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上面的示例 2 和示例 3 输出第一个字段等于指定值的行。


    六、Begin 和 End

    前面提到过,其实awk花括号里的内容,相当于有一个隐藏的循环,不断的一行一行的处理并输出。
    但是,如果花括号用BEGIN和END这两种模式定义了,则不会循环,它有特殊含义。BEGIN定义的模式,故名思义,只会 在循环开始的时候执行一次,而END自然就是循环结束后,再执行。
    下面我们新建一个 demo2.txt

    $ vim demo2.txt
    1 张三 男 22 北京
    2 李四 男 23 上海
    3 王五 女 18 广州 
    4 小红 女 19 桂林 
    5 小安 女 20 杭州 
    6 小达 男 26 深圳 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    执行以下awk语句

    $ awk -v OFS='|' 'BEGIN{print "序号","姓名","性别","年龄","地址","\n------------"} {print $1,$2,$3,$4,$5} END{print "-----------"}' demo2.txt
    
    序号|姓名|性别|年龄|地址|
    ------------
    1|张三||22|北京
    2|李四||23|上海
    3|王五||18|广州
    4|小红||19|桂林
    5|小安||20|杭州
    6|小达||26|深圳
    -----------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    可以看到,BEGIN 部分输出在开头,而 END 部分输出在结尾

    以上的代码相当于下面的代码👇:

    # BEGIN
    print "序号","姓名","性别","年龄","地址","\n------------"
    # Action
    while(!END){
        {print $1,$2,$3,$4,$5};
    }
    # END
    print "-----------"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当然,BEGIN 还可以用来定义变量

    $ awk 'BEGIN { FS=":" } {print $1}' demo2.txt
    1 张三 男 22 北京
    2 李四 男 23 上海
    3 王五 女 18 广州 
    4 小红 女 19 桂林 
    5 小安 女 20 杭州 
    6 小达 男 26 深圳
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    七、if / if else语句

    前面我们输出过偶数行,是这么输出的,是在模式里添加条件的

    $ awk -F ':' 'NR % 2 == 0 {print $1}' demo1.txt
    
    • 1

    现在我们知道了还有 if 语句,所以还可以这么写

    $ awk -F ':' '{if(NR % 2 == 0) print $1}' demo1.txt
    
    • 1

    如果是多条语句

    $ awk -F ':' '{if(NR%2==0){print $1;print $2}}' demo1.txt
    
    • 1
  • 相关阅读:
    蓝桥杯实战应用【算法代码篇】-小朋友崇拜圈(附Java、Python和C++代码)
    LeetCode 2511 最多可以摧毁的敌人城堡数目
    ReactPortals传送门
    Chaos Mesh网络延迟原理探索
    【408篇】C语言笔记-第十章(线性表)
    气膜建筑在施工工期方面的优势
    python基础知识
    esp-idf 移植 lvgl8.3.3
    微慕积分商城插件
    vue中的虚拟dom与真实dom的区别及vuex中的mapState实现原理
  • 原文地址:https://blog.csdn.net/a549654065/article/details/126092443