awk使用

awk用法

文本处理的命令;便于截取内容;支持小数运算


工作原理(与sed区分)

sed一样,均是一行行的读取、处理; sed是一整行处理,awk是将一行拆分成字段进行处理


完整语法

awk 'BEGIN{commands}pattern{commands}END{commands}'file BEGIN 执行数据前的命令

  • pattern 每行都会执行的命令
  • END 执行数据后的命令

例:以:为分隔符,查找passwd文件中以bash结尾,打出第一个字段和第七个字段

[root@localhost 1-28]# cat passwd | awk -F: 'BEGIN{print "--start--"} /bash$/{print $1,$7}END{print "--end--"} '
--start--
root /bin/bash
yalin /bin/bash
califeng /bin/bash
cali123 /bin/bash
zhaoliying /bin/bash
woshi1 /bin/bash
woshi2 /bin/bash
--end--

统计passwd文件行数

[root@localhost 1-28]# cat passwd | awk -F: 'BEGIN{i=0} {i++} END{print i}'

基本用法
  • awk -F分隔符 ‘/模式/{动作}’ 文件;默认分割符是空白(空格或者tab键)
  • awk的指令一定要用单引号括起来,动作一定要用花括号{}括起来
  • 模式是正则表达式,要用/定界符
  • 多个动作之间用;分隔
基本命令示例

只要模式没有动作结果和grep类似,显示$0

	[root@localhost 1-28]# awk '/bash/' passwd 
	root:x:0:0:root:/root:/bin/bash
	yalin:x:1009:1009::/home/yalin:/bin/bash
	califeng:x:1010:1010::/home/califeng:/bin/bash
	cali123:x:1011:1011::/home/cali123:/bin/bash
	zhaoliying:x:1012:1012::/home/zhaoliying:/bin/bash
	woshi1:x:1013:1013::/home/woshi1:/bin/bash
	woshi2:x:1014:1014::/home/woshi2:/bin/bash

截取功能

	[root@localhost 1-28]# who | awk '{print $2}'
	tty1
	pts/0

实现字符串拼接,自定义的字符串需要用""

	[root@localhost 1-28]# who | awk '{print "time:"$4,$2}'
	time:10:29 tty1
	time:10:29 pts/0

~模糊匹配 ==精确匹配 !不匹配

[root@localhost 1-28]# who | awk '$2~"tt" {print $0}'
root     tty1         2021-01-28 10:29
[root@localhost 1-28]# who | awk '$2=="tty1" {print $0}'
root     tty1         2021-01-28 10:29
[root@localhost 1-28]# who | awk '$2!="tty1" {print $0}'
root     pts/0        2021-01-28 10:29 (192.168.0.123)

与界定符号一同连用 \b不识别 只能使用<>

[root@localhost 1-28]# cat passwd | awk -F: '$1 ~ /\<....\>/ {print $1}'
root
sync
halt
mail
dbus
sssd
sshd
rngd

awk内置变量
  • NR 代表当前处理的行号 number of record
  • NF 代表一行的字段数量 number of field
  • FS 当前输入分隔符,默认是空白(空格和tab)
  • FNR 读取文件的记录数(行号),从1开始
  • OFS 当前输出分隔符,默认是空格
    例:输出who中第一个第二个以及最后一个字段,并且用-连接起来
    [root@localhost 1-28]# who | awk 'OFS="-"{print $1,$2,$NF}'
    root-tty1-10:29
    root-pts/0-(192.168.0.123)
    

awk内置函数
  • int(x)返回x的截断至整数的值
    [root@localhost 1-9]# awk 'BEGIN {a=6.1572;result=int(a);print result}'
    6
    
  • rand()
    返回任意数字n(0<=n<1)
    [root@localhost 1-9]# awk 'BEGIN {print rand()}'
    0.924046
    [root@localhost 1-9]# awk 'BEGIN {print rand()}'
    0.924046
    没有设置随机种子,则产生随机数相同
    
  • srand()
    常与rand()一同使用产生随机值
    srand()需要写在BEGIN模块,才能正常产生随机数,这是awk的工作机制决定
    [root@localhost 1-9]# awk 'BEGIN {srand();print rand()}'
    0.501409
    [root@localhost 1-9]# awk 'BEGIN {srand();print rand()}'
    0.0852438
    
  • sub(旧字符串,新字符串,字符串)
    第三个字符串是可选的,默认为$0
    [root@localhost 1-9]# awk 'BEGIN{ str="Hello World!";print "Before:" str;sub("World","Jack",str);print "After:" str }'
    Before:Hello World!
    After:Hello Jack!
    
  • index(字符串1,字符串2)
    在字符串1中查找字符串2,从1开始编号,得到字符串2的值;若没查找到则返回0
    [root@localhost 1-9]# awk 'BEGIN{ str="AA BB CC";subs="BB";ret=index(str,sub);printf ret}'
    4
    
  • ength(字符串)
    返回字符串的长度
    [root@localhost 1-9]# awk 'BEGIN {str="hello!!I am Anna!";print length(str)}' 
    17
    
  • split(字符串,数组,分隔符)
    将字符串根据分隔符分割成一个个数组元素存入数组中
    [root@localhost 1-9]# awk 'BEGIN {str="AA,BB,CC,DD,EE";split(str,arr,",");for(i in arr){ print arr[i]}}'
    AA
    BB
    CC
    DD
    EE
    
  • system
    得到命令返回值;0表示上一条命令执行成功;非0表示上一条命令执行失败
    [root@localhost 1-9]# awk 'BEGIN { ret=system("date");print ret}'
    2021年 01月 09日 星期六 20:48:17 CST
    0
    

awk引用shell变量
  • -v引用shell变量(当变量较少的时候)
    [root@localhost 1-9]# name="lisi"
    [root@localhost 1-9]# echo | awk -v abc=$name '{print abc}'
    lisi
    
  • 用双引号单引号以及$将变量括起来;
    顺序是:双引号单引号$单引号双引号
    [root@localhost 1-9]# awk 'BEGIN{print "'$name'"}'
    lisi
    
  • 使用双引号,awk内部的$0、$n等需要进行转义
    [root@localhost 1-9]# abc=zhaoliying
    [root@localhost 1-9]# awk -F: "/^$abc/{print NR,\$0} " /etc/passwd
    29 zhaoliying:x:1012:1012::/home/zhaoliying:/bin/bash
    [root@localhost 1-9]# awk -F: "/^$abc/{print \$1,\$3} " /etc/passwd
    zhaoliying 1012
    
  • 使用单引号,拼接参数传参
    sg=3
    [root@localhost ~]# awk -F: '/root/{print $1,$'$sg'}' /etc/passwd
    root 0
    operator 11
    -------------------------------------------------------------------
    [root@localhost ~]#awk -F: "/root/{print \$1,\$sg}" /etc/passwd
    root root:x:0:0:root:/root:/bin/bash
    operator operator:x:11:0:operator:/root:/sbin/nologin
    

练习
  • 查看没有设置密码的用户(第二个字段为*或者!!则未设置)
    cat shadow | awk -F: ‘BEGIN{i=0} {length($2)<=2;i++;print $1"没有设置密码"} END{print “有"i"个没有设置密码”}’
  • 使用NF变量显示passwd文件倒数第二列的内容
    cat passwd | awk -F’[: /]’ ‘{print $(NF-1)}’
  • 显示passwd文件中第5到第10行的用户名
    cat passwd | awk -F: ‘{print $1}’ | sed -n ‘5p;10p’
    cat passwd | awk -F: ‘NR ~/<[5-9]|10>/ {print $1}’
  • 显示passwd文件中行号是5结尾的行号和行
    awk -F: ’ NR ~ /5$/ {print NR,$1}’ passwd
  • 用ip add只显示ip(不能使用tr或者cut命令)
    ip add | awk ‘$NF ~/ens33/{print $2}’ | awk -F/ ‘{print $1}’
  • 先使用ifconfig,使用awk显示eth0的入站流量和出站流量(字节)
    ifconfig |head -8 | awk ‘$1 ~/RX/ && $4 ~ /bytes/ || $1 ~ /TX/ && $4 ~ /bytes/ {print $0}’
    ifconfig | head -8 | awk ‘$0 ~ /RX.*bytes|TX.*bytes/ {print $5}’
  • 使用awk命令统计以r开头的用户数目,显示如下效果
    cat passwd | awk -F: ‘BEGIN{i=0} $1 ~ /^r/ {print $1;i++} END {print i};’
  • 显示passwd文件中第7列不是bash的用户名
    cat passwd | awk -F: ‘KaTeX parse error: Undefined control sequence: \< at position 7: 7 !~ /\̲<̲bash>/{print $1}’
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值