Shell—12.awk

awk是一门语言,类似于C语言。awk一般用于统计,过滤,计算。awk按行处理文件


 

基本语法

- awk options pattern{action} file
| awk 可选参数 模式/条件 动作     文件/数据

- awk '条件1{动作1} 条件2{动作2}...' 文件名

- action
| awk擅长文本格式化,且输出格式化后的结果。最常见print和printf
| 除了使用格式流输出,还有用流程控制语句作为action

- pattern
| 一般使用关系表达式作为pattern

- awk 必须外层使用单引号,内层使用双引号
| 内置变量不要加双引号,否则会被识别为文本,尽量不加引号

- options
| -F 指定分割字段符
| -v 定义或修改awk内部的变量
| -f 从脚本文件中读取awk命令

- awk有一些内置变量
| NR  表示行号
| NF  表示列号  倒数就是 NF-X

- 一个等于号是修改变量值,两个等于号是关系运算符。

- awk分割符有两种
| 输入分隔符,awk默认空格,英文field separator,变量名FS
| 输出分隔符,output field separator,简称OFS

--- 提取ip地址示例 ---

[root@wg ~]# ifconfig | awk 'NR==2'
  inet 192.168.3.111  netmask 255..  broadcast 192..

[root@wg ~]# ifconfig | awk 'NR==2{print NF,$0}'
6 inet 192.168.3.111  netmask 255..  broadcast 192..

# 默认直接输出,无分割。加逗号才能在两个变量间输出空格

[root@wg ~]# ifconfig | awk 'NR==2{print $2}'
192.168.3.111

--- 提取用户名示例 ---

[root@wg ~]# awk "NR==5" /etc/passwd
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@wg ~]# awk 'NR==1,NR==3{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

[root@wg ~]# awk -F ":" 'NR==1,NR==3{print $1}' /etc/passwd
root
bin
daemon

[root@wg ~]# awk -v FS=":" 'NR==1,NR==3{print $1}' /etc/passwd
root
bin
daemon

[root@wg ~]# awk -v FS=":" 'NR==1,NR==3{print $1"|"$(NF-0)}' /etc/passwd
root|/bin/bash
bin|/sbin/nologin
daemon|/sbin/nologin

# NF的值是列数,$调取出来当然是最后一列

[root@wg ~]# awk -F ":" -v OFS="|" 'NR==1,NR==3{print $1,$6}' /etc/passwd
root|/root
bin|/bin
daemon|/sbin

 

内置变量

- FS       输入字段分隔符,默认为空
- OFS      输出字段分隔符,默认为空
- RS       输入记录分隔符(输入换行符),指定输入时的换行符
- ORS      输出记录分隔符(输出换行符),输出时用指定符号代替换行符
- FNR      各文件分别计数的行号
- FILENAME 当前文件名
- ARGC     命令行参数的个数
- ARGV     数组、保存的是命令行所给定的各参数

[root@wg ~]# awk -F ":" 'NR==1,NR==3{print $1}' /etc/passwd
root
bin
daemon

[root@wg ~]# awk -v RS=":" 'NR==1,NR==3{print $1}' /etc/passwd
root
x
0

[root@wg ~]# awk -F ":" -v ORS="##" 'NR==1,NR==3{print $1}' /etc/passwd
root##bin##daemon##

[root@wg ~]# awk -F ":" 'NR==1,NR==3{print FILENAME,$1}' /etc/passwd
/etc/passwd root
/etc/passwd bin
/etc/passwd daemon

[root@wg ~]# awk -F ":" 'NR==1,NR==3{print ARGV[0],$1}' /etc/passwd
awk root
awk bin
awk daemon

- ARGV是一个数组,里边默认是 awk 文件名
- 传入1的话,就是文件名

[root@wg ~]# awk -v myname="wg" 'BEGIN{print "我的名字是:",myname}'
我的名字是:wg

[root@wg ~]# myname="wg"
[root@wg ~]# awk -v myname=$myname 'BEGIN{print "我的名字是:",myname}'
我的名字是:wg

操作示例

df -h | grep /home | awk '{print $5}' |cut -d "%" -f 1

- BEGIN  
| awk 'BEGIN{print "test!!"}' {print $2 "\t" $5} student.txt

- FS位置变量 作用是指定分割符
| awk '{FS=":"}{print $1 "\t" $3}' /etc/passwd
| awk 'BEGIN{FS=":"}{print $1 "\t" $3}' /etc/passwd

- END
| awk 'END{printf "The End\n"}{printf $2 "\t" $3 "\n"}' student.txt

- FS
| cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

- 支持关系运算符
| cat student.txt | grep -v Name | awk '$6>=87 {printf $2 "\n"}'

 

模式

[root@wg ~]# awk -F ":" 'BEGIN{print "begin"}NR==1{print $1}' /etc/passwd
begin
root

[root@wg ~]# awk -F ":" 'END{print "begin"}NR==1{print $1}' /etc/passwd
root
begin

操作示例

[root@wg ~]# echo 1:2:3:4|awk 'BEGIN{FS=":";OFS="-"}{NF+=0}1'
1-2-3-4
[root@wg ~]# echo 1:2:3:4|awk 'BEGIN{FS=":";OFS="-"}NF+=0'
1-2-3-4
[root@wg ~]# echo 1:2:3:4|awk 'BEGIN{FS=":";OFS="-"}{NF+=0}{print $0}'
1-2-3-4
[root@wg ~]# echo 1:2:3:4|awk 'BEGIN{FS=":";OFS="-"}NF+=0{print $0}'
1-2-3-4

- BEGIN{} 特殊的pattern,最常用于变量赋值
- BEGIN 这个pattern就是文件没开始读的时候执行
- 'BEGIN{FS=":";OFS="-"}{NF+=0}1' 对应处理是 1:2:3 --> 1-2-3 
- awk有个问题,没有对字段进行操作,它是不会改变输出分隔符的,
- NF+=0,这个赋值没用,NF值也没变仅对字段进行了操作,会使OFS生效
# 总结: 设置OFS,必须进行个字段操作
# 感觉很生涩,远远不如Python好用

--- 半年没写了,凭记忆写一个python ---
print("1:2:3:4".replace(":""-"))    // 忘了加不加逗号了
1-2-3-4

 

print和printf

- 1.printf需要指定formatprint不用指定
| format用于指定后面的每个item的输出格式

- 2.printf不自动打印换行符: \n ;print默认添加空格换行符

- format格式的提示符都以%开头,后缀一个字符
| %c     显示字符的ascii码
| %d,%i  十进制整数
| %e,%E  科学计数法显示数值
| %f     显示浮点数
| %g,%G  以科学计数法的格式或浮点数的格式显示数值
| %s     显示字符串
| %w     无符号整数
| %%     百分号本身

- printf修饰符
| -  左对齐 默认是右对齐
| +  显示数值正负符号 printf "%+d"

[root@wg ~]# awk 'NR==1,NR==3{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

[root@wg ~]# awk 'NR==1,NR==3{printf "%s\n",$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

[root@wg ~]# printf "%d\n%d\n%d\n%d\n" 1 2 3 4
1
2
3
4

 

关系运算符

- 支持关系运算符
- 前边的NR==1,NR==3 直接 NR<4

 

正则的使用

- awk '/正则表达式/动作' 文件
- 正则可以看做是条件了,还可以加普通条件

awk "\$2 ~ /$md$/"  
awk '$2 ~ /'$md'$/'
posted @   梵高de画笔  阅读(37)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示