zoukankan      html  css  js  c++  java
  • linux学习笔记--awk命令详解

    linux学习笔记--awk命令详解

    作用:数据处理工具,用于把一行中分成数个字段处理(切割)

    • 语法规则: awk '条件类型 1 {操作1} 条件类型2 {操作2} ...' filename

    awk主要处理一行内的数据,默认的分隔符为“空格键”或“TAB键”

    • 例:找出登录这着的账号与ip
    [root@localhost ~]# last -n 5
    root     pts/1        192.168.43.99    Thu Mar 12 10:25   still logged in   
    root     tty1                          Thu Mar 12 10:24   still logged in   
    root     pts/0        192.168.43.99    Thu Mar 12 09:55 - 10:26  (00:31)    
    reboot   system boot  3.10.0-1062.12.1 Thu Mar 12 09:55 - 11:12  (01:17)    
    root     pts/0        192.168.43.99    Wed Mar 11 17:06 - down   (00:09)    
    
    wtmp begins Sat Nov 16 04:06:53 2019
    [root@localhost ~]# last -n 5 | awk '{print $1 "	" $3}'
    root	192.168.43.99
    root	Thu
    root	192.168.43.99
    reboot	boot
    root	192.168.43.99
    	
    wtmp	Sat
    

    几个变量的说明($0 $1 $2 ...)

    上面例子中$1是root,是该行第一栏的内容,$3是192.168.43.99 ,是该行第三栏的内容。$0代表一整行数据。

    awk处理流程

    1. 读入第一行,将第一行数据写入$0 $1 $2...中
    2. 根据“条件类型”的限制判断是否进行后面“操作”(上例中因为每行都要操作,因此没有设置条件类型)
    3. 若为多行,则在重复执行1,2

    awk内置变量

    变量名称 含义
    NF 每行($0)拥有的字段数
    NR 目前awk所处理第几行
    FS 目前分割字符,默认为空格键
    FILENAME awk浏览的文件名
    ... ...
    • 例:在上例中列出每行行号($1);列出目前处理行数;列出该行字段数
    [root@localhost ~]# last -n 5 | awk '{print $1 "	 lines: " NR "	 columns:" NF}'
    root	 lines: 1	 columns:10
    root	 lines: 2	 columns:9
    root	 lines: 3	 columns:10
    reboot	 lines: 4	 columns:11
    root	 lines: 5	 columns:10
    	 lines: 6	 columns:0
    wtmp	 lines: 7	 columns:7
    

    awk逻辑运算符

    运算单元 含义
    > 大于
    < 小于
    >= 大于等于
    <= 小于等于
    == 等于
    != 不等于

    实验练习

    • 例:列出/etc/passwd中第一个字段用户,第三个字段UID,并设置仅查看第三栏小于10的数据
    [root@localhost ~]# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "	" $3}'
    root:x:0:0:root:/root:/bin/bash	
    bin	1
    daemon	2
    adm	3
    lp	4
    sync	5
    shutdown	6
    halt	7
    mail	8
    

    这有一个为问题:第一行没有正确分割,因为读第一行时默认还是以空格键分割 (--感觉是个缺陷呀)

    解决方法:预先设置awk变量,利用BEGIN关键词

    [root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "	" $3}'
    root	0
    bin	1
    daemon	2
    adm	3
    lp	4
    sync	5
    shutdown	6
    halt	7
    mail	8
    
    [root@localhost ~]# awk  '/root/' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    
    [root@localhost ~]# awk -F: '/root/ {print $7}' /etc/passwd  //-F: 等效于FS=":"
    /bin/bash
    /sbin/nologin
    
    • 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容
    [root@localhost ~]# awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd | head -n 5
    filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
    filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin
    filename:/etc/passwd,linenumber:3,columns:7,linecontent:daemon:x:2:2:daemon:/sbin:/sbin/nologin
    filename:/etc/passwd,linenumber:4,columns:7,linecontent:adm:x:3:4:adm:/var/adm:/sbin/nologin
    filename:/etc/passwd,linenumber:5,columns:7,linecontent:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    • 使用printf替代print,可以让代码更加简洁,易读
    [root@localhost ~]# awk -F: '{printf ("filename:%10s, linenumber:%3s,column:%3s,content:%4s
    ",FILENAME,NR,NF,$0)}' /etc/passwd | head -n 5
    filename:/etc/passwd, linenumber:  1,column:  7,content:root:x:0:0:root:/root:/bin/bash
    filename:/etc/passwd, linenumber:  2,column:  7,content:bin:x:1:1:bin:/bin:/sbin/nologin
    filename:/etc/passwd, linenumber:  3,column:  7,content:daemon:x:2:2:daemon:/sbin:/sbin/nologin
    filename:/etc/passwd, linenumber:  4,column:  7,content:adm:x:3:4:adm:/var/adm:/sbin/nologin
    filename:/etc/passwd, linenumber:  5,column:  7,content:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    • 打印/etc/passwd/的第二行信息
    [root@localhost ~]# awk -F: 'NR==2{print "filename: "FILENAME, $0}' /etc/passwd
    filename: /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin
    
    • 指定特定的分隔符,查询第一列
    [root@localhost ~]# awk -F ":" '{print $1}' /etc/passwd | head -n 8
    root
    bin
    daemon
    adm
    lp
    sync
    shutdown
    halt
    
    • 指定特定的分隔符,查询最后一列
    [root@localhost ~]# awk -F ":" '{print $NF}' /etc/passwd | tail -n 5
    /bin/bash
    /bin/bash
    /bin/bash
    /bin/bash
    /sbin/nologin
    
    • 指定特定的分隔符,查询倒数第二列
    [root@localhost ~]# awk -F ":" '{print $(NF-1)}' /etc/passwd | head -n 5
    /root
    /bin
    /sbin
    /var/adm
    /var/spool/lpd
    
    • 获取第12到31行的第一列的信息
    [root@localhost ~]# awk -F ":"  '{if(NR<31 && NR >12) print $1}' /etc/passwd
    nobody
    systemd-network
    dbus
    polkitd
    libstoragemgmt
    colord
    rpc
    saslauth
    abrt
    setroubleshoot
    rtkit
    radvd
    gluster
    chrony
    qemu
    unbound
    tss
    usbmuxd
    
    • 多分隔符的使用 (这里以/为分隔符,多个分隔符利用[]然后在里面写分隔符即可 )
    [root@localhost ~]#  awk -F "[/]" 'NR == 4 {print $0,"
    ",$1}' /etc/passwd
    adm:x:3:4:adm:/var/adm:/sbin/nologin 
     adm:x:3:4:adm:
    
    生活是一首长长的歌!
  • 相关阅读:
    Linux主要shell命令详解(下)
    mget命令, ftp命令详解
    VI 基本可视模式
    vim使用技巧
    cd及目录快速切换
    du命令解决linux磁盘空间满的问题(很不错的哦)
    Mysql删除数据后磁盘空间未释放的解决办法【转】
    MYSQL-innodb性能优化几个点
    Apache服务器出现Forbidden 403错误提示的解决方法总结
    MySQL 分区表原理及数据备份转移实战
  • 原文地址:https://www.cnblogs.com/wind-zhou/p/12829192.html
Copyright © 2011-2022 走看看