Shell awk命令
时间:2022-07-24
本文章向大家介绍Shell awk命令,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
awk 语法结构
awk [options] 'commands' file(s)
option:
-F 定义字段分割符号
-v 定义变量并赋值
command:
1、范围说明或者正则表达式或者{awk命令语句1;awk命令语句2;}
2、范围说明部分可以是BEGIN、END、逻辑表达式或者为空
3、awk命令语句间用分号间隔
4、引用shell变量时需要用双引号引起,命令模式都在单引号''里面
BEGIN{} {} END{}
行处理前 行处理 行处理后
字段分割及相关变量
$1,$2,$3...$n:awk中用该顺序形式表示files中每行以间隔符号分割的各列的不同字段
$0 表示文本本身
NF 表示当前记录的字段数(列数)
$NF 最后一列
$(NF-1) 倒数第二列
FNR/NR 行号
FILENAME 文件名
"t" 制表符
RS/ORS 换行符
"" 打印字符串
FS/OFS 定义间隔符
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
/[0-9][0-9]+/ 两个或两个以上数字
-F'[:#/]' 定义三个分隔符
常用内置变量举例
awk -F: '{print $0}' /etc/passwd #打印文件所有内容
awk -F: '{print NR, $0}' /etc/passwd /etc/hosts #打印文件所有内容,并包括行号
awk -F: '{print FNR,$0}' /etc/passwd /etc/hosts
awk -F: '{print $0,NF}' /etc/passwd #保留记录的字段数
awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd #输入字段分隔符,默认为空格
分隔符
[root@linux /]# echo "aa bb cc"|awk '{print $2}' #分隔空格
bb
[root@linux /]# echo "aa bb cc"|awk -F " " '{print $2}' #分隔空格
bb
[root@linux /]# awk -F: '{print $1}' /etc/passwd|wc -l #统计系统用户数
33
指定多个分隔符
[root@linux /]# echo "11 22 33:44:55"|awk -F"[ :]" '{print $2}'
22
[root@linux /]# echo "11-22-33:44:55"|awk -F"[-:]" '{print $3}'
33
使用FS和OFS指定分隔符
[root@linux /]# echo "aaa222bbb"|awk 'BEGIN{FS="222";OFS=":"}{print $2}'
bbb
[root@linux /]# head -1 /etc/passwd >passwd
[root@linux /]# awk -F: 'BEGIN{OFS="-"}{print $1,$2,$3}' passwd
root-x-0
换行符
[root@linux /]# cat xxx.txt
127.0.0.1
[root@linux /]# awk 'BEGIN{RS="."}{print $0}' xxx.txt
127
0
0
1
[root@linux /]# cat xxx.txt
127.0.0.1
hello
world
[root@linux /]# awk 'BEGIN{ORS=" "}{print $0}' xxx.txt #将多行内容合并成一行
127.0.0.1 hello world
格式化输出
print函数
[root@linux /]# date|awk '{print "Year:" $NF "nMonth:" $2 "nDay:" $3}' #显示年月日
Year:2020
Month:Aug
Day:15
[root@linux /]# awk -F: '{print "User:" $1 "t Shell:" $NF}' /etc/passwd
[root@linux /]# awk -F: '{print "User: " $1,$NF}' /etc/passwd
printf函数
awk -F: '{printf "%-15s %-10s %-15sn", $1,$2,$3}' /etc/passwd
awk -F: '{printf "|%15s| %10s| %15s|n", $1,$2,$3}' /etc/passwd
awk -F: '{printf "|%-15s| %-10s| %-15s|n", $1,$2,$3}' /etc/passwd
参数解释:
%s 字符类型 strings %-20s
%d 数值类型
占15字符
- 表示左对齐,默认是右对齐
printf默认不会在行尾自动换行,加n
awk的模式和动作
正则表达式
awk '/^root/' /etc/passwd #匹配root开头的行
awk '!/^root/' /etc/passwd #匹配除了root开头的行
模式匹配表达式
awk -F: '$1 ~ /^admin/' /etc/passwd
awk -F: '$NF !~ /nologin/' /etc/passwd
比较表达式
比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。比较表达式使用关系运算符,用于比较数字与字符串
运算符 含义
< 小于
<= 小于或等于
== 等于
!= 不等于
>= 大于等于
> 大于
[root@linux /]# awk -F: '$1 == "root" ' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@linux /]# awk -F: '$NF == "/bin/bash" ' /etc/passwd
root:x:0:0:root:/root:/bin/bash
admin:x:1000:1000::/home/admin:/bin/bash
[root@linux /]# awk -F: '$3 < 10 ' /etc/passwd
运算符
+ - * / 加减乘除
[root@linux /]# cat xxx.txt
10 2
[root@linux /]# awk '{print $1 / $2}' xxx.txt #除
5
[root@linux /]# awk '{print $1 * $2}' xxx.txt #乘
20
[root@linux /]# awk '{print $1 - $2}' xxx.txt #减
8
逻辑运算符
&& 逻辑与 a&&b
|| 逻辑或 a||b
! 逻辑非 !a
[root@linux /]# awk -F: '$3==0 && $NF=="/bin/bash" {print $1 "t" $NF}' /etc/passwd
root /bin/bash
[root@linux /]# awk -F: '$3==0||$NF=="/bin/bash" {print $1 "t" $NF}' /etc/passwd
root /bin/bash
admin /bin/bash
[root@linux /]# awk -F: '!($3 == 0 || $3 <=10)' /etc/passwd
awk脚本模式
条件判断
if语句
{if(表达式){语句;语句;...}}
[root@linux /]# awk -F: '{if($3==0){print $1 "tadmiinistrator"}}' /etc/passwd
root admiinistrator
[root@linux /]# awk -F: '{if($1){count++}} END{print count}' /etc/passwd #统计系统用户数
45
[root@linux /]# awk 'BEGIN{if('$(id -u)'==0) {print "administrator"} }'
administrator
if...else语句
格式:
{if(表达式){语句;语句;...}else{语句;语句;...}}
[root@linux /]# awk -F: '{if($3==0){print $1"t这是管理员"}else{print $1"t这是普通用户"}}' /etc/passwd
[root@linux /]# awk -F: '{if($3==0){x++} else{i++}} END{print "管理员个数: "x ; print "系统用户数: "i}' /etc/passwd
管理员个数: 1
系统用户数: 32
if...else if...else语句
{if(表达式1){语句;语句;...}else if(表达式2){语句;语句;...}else if(表达式3){语句;语句;...}else{语句;语句;...}}
awk -F: '{if($3==0){print "我是管理员用户"$1}else if($3<999){print "我是系统用户"$1}else if($3>1000){print "我是普通用户"$1}}' /etc/passwd
循环
while循环
awk 'BEGIN{i=1; while(i<=10){print i; i++}}'
awk 'BEGIN{ip="192.168.1."; i=1; while(i<255){print ip i;i++}}'
for循环
awk 'BEGIN{for(i=0;i<5;i++){print i}}'
awk 'BEGIN{for(i=1;i<=5;i+=2){print i}}'
awk -F: '{for(i=1;i<=10;i++) print $0}' /etc/passwd
数组
[root@linux /]# awk -F: '{user[i++]=$1}END{print user[0]}' /etc/passwd
root
[root@linux /]# awk -F: '{user[i++]=$1}END{print user[1]}' /etc/passwd
bin
[root@linux /]# awk -F: '{user[i++]=$1}END{print user[2]}' /etc/passwd
daemon
[root@linux /]# cat /etc/passwd|head -3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
数组遍历
统计Shell
[root@linux /]# awk -F: '{shell[$NF]++}END{for(i in shell){print i,shell[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 2
/sbin/nologin 25
/sbin/halt 1
/sbin/shutdown 1
统计登录SSH失败的用户
[root@linux /]# lastb|awk '{name[$1]++}END{for(i in name){print i,name[i]}}'|sort -k2rn|head -3
root 393
ubuntu 92
test 90
统计网站访问状态
[root@linux /]# ss -an|grep :80|awk '{x[$2]++}END{for(i in x){print i,x[i]}}'|sort -k2rn
ESTAB 24
TIME-WAIT 3
LISTEN 1
- 今天处理的三个小问题——20160120(r7笔记第84天)
- 主备切换的准备工作(r7笔记第83天)
- Java设计模式-外观模式
- Java设计模式-组合模式
- 使用shell批量监控磁盘坏块(二) (r7笔记第80天)
- JavaWeb10-request&response你不得不学(1)
- dg的奇怪问题终结和分区问题答疑 (r7笔记第77天)
- 最近让我焦灼的四个问题(有解) (r7笔记第76天)
- JavaWeb10-reques;response你不得不学(2)
- 很多人比较纠结的约束和索引的关系(r7笔记第75天)
- JavaWeb09-Servlet(Java真正的全栈开发)
- JavaWeb08-XML,tomcat,HTTP轻松入门
- JavaWeb07-JDBC(Java真正的全栈开发)
- 编程思想 之「操作符」
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- OkHttp请求耗时统计
- Ubuntu 18.04 通过 Docker 快速部署 Smokeping 2.6.11 教程
- MySQL 8.0新特性 — 函数索引
- Docker快速上手指北(一)【技术创作101训练营】
- leetcode树之二叉搜索树的最近公共祖先
- 【技术创作101训练营】技术角 | 在CentOS 8上使用Nginx 1.18: 基本配置
- Java诊断应用之Arthas实战(技术创作101训练营)
- 突击并发编程JUC系列-数组类型AtomicLongArray
- 个人量化投资体系搭建(一)
- 服务端的 WebAssembly 与 Rust 入门篇
- pImpl
- Flask+requests发起页面请求示例
- 【技术创作101训练营】Git 如何成功配置SSH key连接多个代码平台?
- 深入浅出iOS内存管理-技术创作101训练营
- 聊聊原型 Prototype | 技术创作101训练营