Linux awk 使用

参考文章:Linux三剑客之awk命令 - 琴酒网络 - 博客园

1. awk

1.1 简介

awk的最基本功能是在文件或者字符串中指定规则浏览和抽取信息。

通常,awk 是以行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk的基本用法:

awk '{pattern + action}' {filenames}

(base) echo -e "first test line\nsecond test line" | awk '{print "hello word"}'
hello word
hello word

通过echo输出两行文本,针对每行文本使用awk输出hello world,可见一共输出了两次。

这里awk只在 {} 中使用了 print, 也可以在 {} 中使用多条命令组合

awk 输入

  • 直接通过管道 | 接收标准输出的文本内容进行处理

  • 直接在命令末尾指定待处理文本文件名如:/etc/passwd

    (base) awk '{print $0}' /etc/passwd
    
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    ...
    

1.2 常用变量、参数

1.2.1处理规则

awk 功能是将读取的文本内容的每一行按照一定规则进行抽取、处理、输出;

  1. 读取每一行文本,按照指定的字段分割符(field separator),默认为空白,将每一行分割成若干字段

  2. 按照需求提取需要的字段:提取当前文本记录行:$0, 提取第一个字段:$1, 依次类推

  3. 对提取的字段按照需求进行处理: 直接输出,变量数值运算,字符拼接…

  4. 按照需求输出文本: 主要是指定输出字段分隔符以及每条记录的分割符

1.2.2 BEGIN和END模块

awk 处理输入文件之前允许定义一个BEGIN模块,主要可以用于初始化变量;还可以定义一个END块用于在处理完文件所有行后,进行结果输出、总结之类的操作。

实例:统计/etc/passwd的账户人数

(base) awk 'BEGIN{count=0;} {count++; print $0;} END{print "total user count: ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
......
total user count:  18

1.2.3 内置变量

图为 /etc/passwd 文件的前两行内容,用来说明awk常用变量

awk 变量说明

  • FS 字段分隔符(field separator),{FS=“:”} 指定冒号分隔符

  • $0 当前记录,默认是当前处理的一行文本内容

  • $nn个字段的值,使用冒号分割时,$1即为字符串root

  • NF 字段数量(number field), 使用冒号分割符时,NF=7,共有7个字段

  • RS 记录分隔符(recorder separator), 默认使用换行符**\n**作为记录分隔符,此时一行文本内容,就是一条记录,一个处理单元

  • NR 记录数量,使用换行符为记录分隔符时,就是文本的所在行数

  • OFS 输出字段分隔符(output field separator)

  • ORS 输出记录分隔符(ouput recorder separator), 默认使用换行符 \n作为输出记录分隔符

1.2.4 使用实例

现在取出 /etc/passwd 的前四行说明各个变量的作用

head -n 4 /etc/passwd

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

head -n 4 /etc/passwd > passwd_4.txt

FS指定字段分割符也可以使用 -F参数进行替代

  • 实例1:输出以冒号为字段分割符的最后一列内容, NF变量为字段数目,$NF即表示最后一个字段的内容
(base) awk 'BEGIN{FS=":"} {print $(NF)}' passwd_4.txt
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin

(base) awk -F ":" '{print $(NF)}' passwd_4.txt
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin

同时指定多个分隔符

  • 实例2:输出以 冒号 和 / 为字段分割符的倒数第二列内容

    (base) awk 'BEGIN{FS="[/:]"} {print $(NF-1)}' passwd_4.txt
    bin
    sbin
    sbin
    sbin
    
    (base) awk -F "[:/]" '{print $(NF-1)}' passwd_4.txt
    bin
    sbin
    sbin
    sbin
    
  • 实例3:按照冒号分割,输出当前字段数目 NF

    (base) awk -F ":" 'END {print NF}' passwd_4.txt 
    7
    
  • 实例4: 输出当前文档内容并添加行号:NR

    (base) awk '{print NR " " $0}' passwd_4.txt 
    1 root:x:0:0:root:/root:/bin/bash
    2 bin:x:1:1:bin:/bin:/sbin/nologin
    3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
    4 adm:x:3:4:adm:/var/adm:/sbin/nologin
    
  • 实例5:输出文件第2-3

    (base) awk '{ if(NR>=2 && NR<=3) {print $0}}' passwd_4.txt 
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    
  • 实例6:输出第1、2个字段,字段之间通过 # 号连接,不同记录之间的分割符为两个换行符

    (base) awk -F ":" 'BEGIN{OFS="#"; ORS="\n\n"} {print $1,$2}' passwd_4.txt 
    root#x
    
    bin#x
    
    daemon#x
    
    adm#x
    
    adm#x
    
    
    

1.3 正则匹配

awk 正则匹配的形式为:

  • 对整条记录进行匹配:awk ‘/匹配模式/{操作}’
  • 对指定字段进行匹配:awk ‘字段~/匹配模式/{操作}’

下面通过实例演示awk的正则使用方式:

首先创建一个ip.txt测试文件,内容如下:

user ip
root 192.168.1.1
root 172.16.0.11
zhang1 192.168.1.12
zhang2 172.16.0.12
zhang3 192.168.0.13
li1 172.18.2.34
ma1 1234
ma2 5678
wang1 10.20.1.34
wang2 172.16.3.25
  • 实例1:找出文件中所有符合用户名 ip 格式的行

    (base) awk '$2~/[0-9]{1,3}\.[0-9]{1,3}\./{print $0}' ip.txt 
    root 192.168.1.1 
    root 172.16.0.11
    zhang1 192.168.1.12
    zhang2 172.16.0.12
    zhang3 192.168.0.13
    li1 172.18.2.34
    wang1 10.20.1.34
    wang2 172.16.3.25
    
  • 实例2:找出文件中192.168网段的文本行

    (base) awk '$2~/192\.168\./{print $0}' ip.txt 
    root 192.168.1.1 
    zhang1 192.168.1.12
    zhang3 192.168.0.13
    
  • 实例2: 找出文件中zhang 姓并且时192.168网段的文本

    (base) awk '($1~/zhang/) && ($2~/192.168./) {print $0}' ip.txt 
    zhang1 192.168.1.12
    zhang3 192.168.0.13
    

1.4 字符串函数

s1
s2

  • 字符替换
    在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info 未
    给 info 值,默认是$0

    awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
    this is a test!test!
    
  • 查找

    (base) awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
    ok 
    
  • 截取

    (base) awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
    s is a tes
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值