当前位置: 首页 > news >正文

shell编程之文本三剑客grep、sed、awk

文章目录

  • 前言
  • 1、grep
    • 1.1 概述
    • 1.2 案例
  • 2、sed
    • 2.1 概述
    • 2.2 案例
      • 2.2.1 输出文本
      • 2.2.2 删除文本
      • 2.2.3 替换文本
      • 2.2.4 迁移文本
      • 2.2.5 使用脚本编辑文件
  • 3、awk
    • 3.1 概述
    • 3.2 命令格式
    • 3.3 实战案例
      • 3.3.1 文本
      • 3.3.2 内置变量
      • 3.3.3 awk运算
      • 3.3.4 模糊匹配
      • 3.3.5 比较符号
      • 3.3.6 逻辑运算
      • 3.3.7 awk结合语句

前言

Shell编程中的文本三剑客(grep、sed、awk)是Linux/Unix环境下最强大的文本处理工具组合,各自擅长不同的文本处理场景
grep‌

  • 功能:文本过滤工具,主要用于搜索匹配特定模式的行
  • 应用场景:日志过滤、配置文件检查

sed‌

  • 功能:流编辑器,擅长行级文本编辑
  • 工作流程:读取→执行→显示循环处理每行文本

awk‌

  • 功能:文本分析工具,擅长列处理和格式化输出
  • 应用场景:数据统计、报表生成

三者的典型配合:先用grep筛选目标行,再用sed进行编辑处理,最后用awk格式化输出和分析

1、grep

1.1 概述

核心功能

  • 文本搜索:在文件或输入流中匹配指定模式(支持正则表达式)
  • 模式筛选:支持正向/反向匹配、整词/整行匹配
  • 上下文展示:可显示匹配行前后若干行内容(调试日志场景常用)
  • 递归搜索:支持目录层级遍历搜索

基础语法

grep [选项] 模式 [文件...]## 当不指定文件时,默认从标准输入读取数据

常用选项分类

-i			忽略大小写
-v			反向匹配
-o			只输出匹配内容
-n			显示行号
-c			统计匹配行数
--include	指定文件类型
--exclude	排除特定文件
-r			递归搜索目录
-A n		显示匹配行后n行
-B n		显示匹配行前n行
-C n		显示匹配行前后各n行

1.2 案例

## 筛选关键字在.log 文件
grep "error" /var/log/vmware-network.log
## 忽略大小写
grep -i "the" demo
## 显示apple出现的行数
grep -c apple sg
## 显示不是apple的内容
grep -v apple sg
## 只显示匹配内容
ifconfig | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'
## 只搜索.txt文件里的apple
grep -r --include="*.txt" "apple" ./
## 搜索除.txt文件之外的文件的apple
grep -r --exclude="*.txt" "apple" ./
## 匹配行后3行
grep -A 3 "apple" sg
## 匹配行前3行
grep -B 3 "banana" sg
## 匹配行前后各3行
grep -C 3 "pear" sg

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2、sed

2.1 概述

sed是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行

sed 的工作流程主要包括读取执行显示三个过程。

  • 读取: sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)
  • 执行: 默认情况下,所有的 sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed 命令将会在所有的行上依次执行
  • 显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完
选项	含义
-e	进行多次编辑
-n	取消默认输出
-f	指定sed文件名
-i	直接在源文件中修改
-r	使用扩展正则表达式命令动作	含义
p	打印输出
d	删除指定行
i	在指定行之前插入内容
a	在指定行后面插入内容
c	替换指定行所有内容
s	搜索替换

2.2 案例

2.2.1 输出文本

## 输出demo所有内容
sed -n 'p' demo 
## 输出第三行
sed -n '3p' demo
## 输出3~5行
sed -n '3,5p' demo
## 输出所有奇数行
sed -n 'p;n' demo
## 输出所有偶数行
sed -n 'n;p' demo
## 输出第 1~5 行之间的奇数行(135)
sed -n '1,5{p;n}' demo
## 输出第 10 行至文件尾之间的偶数行
sed -n '10,${n;p}' demo
## 输出包含the的行
sed -n '/the/p' demo
## 输出包含the的行号
sed -n '/the/=' demo
## 输出以PI开头的行
sed -n '/^PI/p' demo
## 输出以数字结尾的行
sed -n '/[0-9]$/p' demo
## 输出包含单词wood的行
sed -n '/\<wood\>/p' demo

2.2.2 删除文本

nl 命令用于计算文件的行数

## 删除第三行
nl demo | sed '3d'
## 删除3~5行
nl demo | sed '3,5d'
删除包含cross的行
nl demo |sed '/cross/d'
## 删除小写字母开头的行
sed '/^[a-z]/d' demo
## 删除以"."结尾的行
sed '/\.$/d' demo
## 删除所有空行
sed '/^$/d' demo

2.2.3 替换文本

## 将每行的第一个the换成THE
sed 's/the/THE/' demo
## 将每行第二个l换成L
sed 's/l/L/2' demo
## 将文件中所有the替换为THE
sed 's/the/THE/g' demo
## 将文件所有o删除
sed 's/o//g' demo
## 每行行首插入#
sed 's/^/#/' demo
## 包含the的行每行行首插入#
sed '/the/s/^/#/' demo
## 每行行尾插入EOF
sed 's/$/EOF/' demo
## 将第3~5行中所有the替换成THE
sed '3,5s/the/THE/g' demo
## 将包含the的所有行o替换成O
sed '/the/s/o/O/g' demo## 修改配置文件中 禁用模式改为强制模式
sed -i.bak 's/SELINUX=disabled/SELINUX=enable/' /etc/selinux/config 

2.2.4 迁移文本

  • H:复制到剪贴板
  • g/G:将剪贴板中的数据覆盖/追加至指定行
  • w:保存为文件
  • r:读取指定文件
  • a:追加指定内容
  • i:忽略大小写
## 将包含the的行迁移至行尾
sed '/the/{H;d};$G' demo
## 将第 1~5 行内容转移至第 17 行后
sed '1,5{H;d};17G' demo
## 将包含the 的行另存为文件 out.file
sed '/the/w out.file' demo
## 将文件sg 的内容添加到包含 the 的每行以后
sed '/the/r sg' demo
## 在第 3 行后插入一个新行,内容为New
sed '3aNew' demo
## 在包含the 的每行后插入一个新行,内容为 New
sed '/the/aNew' demo
## 在第 3 行后插入多行内容,中间的\n 表示换行
sed '3aNew1\nNew2' demo

2.2.5 使用脚本编辑文件

## 将第 1~5 行内容转移至第 16 行后
sed '1,5{H;d};16G' demo
## 可以用脚本方式来实现
## 创建文件
vim ml
1,5H
1,5d
16G
## 执行文件里的命令
sed -f ml demo

3、awk

3.1 概述

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具

  • 它是专门为文本处理设计的编程语言,也是行处理软件,通常用于扫描、过滤、统计汇总工作
  • 数据可以来自标准输入也可以是管道或文件

工作原理

  • 逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令
  • 将一行分成多个""字段"然后再进行处理
  • 执行结果可以通过print的功能将字段数据打印显示

工作流程
1、开始执行BEGIN模块命令
2、读入数据—Read
3、对读入的数据执行body块中的命令—Execute
4、重复2、3操作指导文件结尾—Repeat
5、执行END模块命令

3.2 命令格式

格式:awk关键字    选项      命令部分  '{xxxx}'   文件名
  • FS:指定每行文本的字段分隔符,默认为空格或制表位
  • NF:当前处理的行的字段个数。在执行过程中对应于当前的字段数,NF:列的个数
  • NR:当前处理的行的行号(序数)。 在执行过程中对应于当前的行号
  • $0:当前处理的行的整行内容
  • $n:当前处理行的第 n 个字段(第 n 列)。比如: $1 表示第一个字段,$2 表示第二个字段
  • FILENAME:被处理的文件名(当前输入文件的名)
  • FNR 各文件分别计数的行号
  • OFS 输出字段分隔符(默认值是一个空格)
  • ORS 输出记录分隔符(默认值是一个换行符)
  • RS:行分隔符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录, 而awk一次仅读入一条记录,以进行处理。默认值是" \n’

3.3 实战案例

3.3.1 文本

cat /etc/passwd | head -10 > zz
## 打印zz里的内容
awk '{print}' zz
## 打印zz里打第一列,默认空格/tab建分割
awk '{print $1}' zz
## 以:分割,打印第五列内容
awk -F: '{print $5}' zz
## 以x分割,打印第一列内容
awk -Fx '{print $1}' /etc/passwd
## 打印第一、二列
awk '{print $1 $2}' zz1
## 第一和第二列中间加一个空格,用双引号引起来
awk '{print $1""$2}' zz1
## 逗号默认空格效果
awk '{print $1,$2}' zz1 
## 制表符作为分隔符输出
awk -F: '{print $1"\t"$2}' /etc/passwd
## 定义多个分隔符
awk -F[:/] '{print $9}' zz

3.3.2 内置变量

常用的内置变量

  • $1:代表第一列
  • $2:代表第二列
  • $0:代表整行
  • NF:一行的列数
  • NR:行数
## 打印包含root的行
awk -F: '/root/{print $0}' zz
## 打印包含root的行的第一列
awk -F: '/root/{print $1}' zz
## 打印包含root的行的第一列和第六列
awk -F: '/root/{print $1,$6}' zz
## 打印每一行的列数
awk -F[:/] '{print NF}' zz
## 显示行号
awk -F[:/] '{print NR}' zz
## 显示行号和整行内容
awk -F: '{print NR,$0}' zz
## 打印第二行
awk -F: 'NR==2' /etc/passwd 
## 打印第二行的第一列
awk -F: 'NR==2{print $1}' /etc/passwd
## 打印最后一列
awk -F: '{print $NF}' /etc/passwd
## 打印总行数
awk 'END{print NR}' /etc/passwd
## 打印最后一行
awk 'END{print $0}' /etc/passwd
## 当前行有几列
awk  -F: '{print "当前行有"NF"列"}' zz
## 第几行有几列
awk -F: '{print "第"NR"行有"NF"列"}' /etc/passwd
## 本机ip
ifconfig ens33 | awk '/netmask/{print "本机的ip地址是"$2}'
## 接受字节数
ifconfig ens33 | awk '/RX p/{print $5"字节"}'
## 根分区可用量
df -h | awk 'NR==2{print $4}'
## FS定义以冒号分割
awk 'BEGIN{FS=":"}{print $1}' pass.txt
## OFS定义输出以---分割
awk 'BEGIN{FS=":";OFS="---"}{print $1,$2}' pass.txt
## FNR读取文件记录数,新的文件重新开始计数
awk '{print FNR,$0}' /etc/resolv.conf /etc/hosts
## NR读取文件行号,不重新计数
awk '{print NR,$0}' /etc/resolv.conf /etc/hosts
## RS指定冒号为换行符
awk 'BEGIN{RS=":"}{print $0}' /etc/passwd
## ORS输出行之间定义以空格分割
awk 'BEGIN{ORS=" "}{print $0}' /etc/passwd

3.3.3 awk运算

awk 'BEGIN{x=10;print x+1}'
awk 'BEGIN{x=10;x++;print x}'
awk 'BEGIN{print x+1}'
awk 'BEGIN{print 2.5+3.5}' 
awk 'BEGIN{print 2-1}'
awk 'BEGIN{print 3*4}'
awk 'BEGIN{print 3**2}'
awk 'BEGIN{print 2^3}'  
awk 'BEGIN{print 1/2}' 

3.3.4 模糊匹配

## 冒号分割,包含root打印出来
awk -F: '/root/' /etc/passwd 
## 冒号分割,第一列包含ro打印处理
awk -F: '$1~/ro/' /etc/passwd
## 冒号分割,第七列不包含nologin的打印出来第一列和第七列
awk -F: '$7!~/nologin/{print $1,$7}' /etc/passwd

3.3.5 比较符号

比较符号:== != <= >= < >

## 打印行数为5
awk  'NR==5{print}' /etc/passwd
## 打印行数小于5
awk  'NR<5' /etc/passwd
## 打印第三列为0的行
awk -F: '$3==0' /etc/passwd
## 打印第一列为root的行
awk -F: '$1=="root"' /etc/passwd
## 打印第三列大于等于1000的行
awk -F: '$3>=1000' /etc/passwd

3.3.6 逻辑运算

  • && 要求所有条件都为真时才为真,否则为假
  • || 只要有一个条件为真就为真,全为假时才为假
awk -F: '$3<10 || $3>=1000' /etc/passwd
awk -F: '$3>10 && $3<1000' /etc/passwd
awk -F: 'NR>4 && NR<10' /etc/passwd

3.3.7 awk结合语句

## 第三列小于10的打印整行
awk -F: '{if($3<10){print $0}}' /etc/passwd
## 第三列小于10的打印第三列,否则打印第一列
awk -F: '{if($3<10){print $3}else{print $1}}' /etc/passwd
## 结合数组和for循环
awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print i,a[i]}}'
## 统计httpd访问日志中每个ip出现的次数
awk '{a[$1]+=1;} END {for(i in a){print a[i]" "i;}}' /var/log/httpd/access_log | sort -r
awk '{ip[$1]++;}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log | sort -r

文章转载自:

http://BENwfOOf.ksqyj.cn
http://Dl1geeX1.ksqyj.cn
http://Bs58ipqN.ksqyj.cn
http://TnD81Uah.ksqyj.cn
http://OXL8fDtX.ksqyj.cn
http://BrVgVpXr.ksqyj.cn
http://WoUxYyEP.ksqyj.cn
http://pzpPOyXj.ksqyj.cn
http://W3ade3wN.ksqyj.cn
http://9bgzUBxi.ksqyj.cn
http://6I1gN6Ww.ksqyj.cn
http://MCHUB3lV.ksqyj.cn
http://mQsdRvaD.ksqyj.cn
http://w6sE0JVD.ksqyj.cn
http://X7g48eja.ksqyj.cn
http://en7KJAyc.ksqyj.cn
http://EmebIckS.ksqyj.cn
http://k80FofAW.ksqyj.cn
http://uwMdPeTC.ksqyj.cn
http://sKLWNOyi.ksqyj.cn
http://N3CH1dhF.ksqyj.cn
http://gHkWmrUf.ksqyj.cn
http://4NnoAaAP.ksqyj.cn
http://UMhUrY7f.ksqyj.cn
http://OREffIFG.ksqyj.cn
http://yYw9qPEf.ksqyj.cn
http://MQK4uU7L.ksqyj.cn
http://M9XNn4t9.ksqyj.cn
http://rhTtuZYe.ksqyj.cn
http://mdSRaZiS.ksqyj.cn
http://www.dtcms.com/a/372631.html

相关文章:

  • 开始 ComfyUI 的 AI 绘图之旅-文生图(一)
  • 有哪些任务可以使用无监督的方式训练深度学习模型?
  • 从零开始构建图注意力网络:GAT算法原理与数值实现详解
  • FastAPI基础
  • 通过SSH来推送本地文件夹到Github
  • 风锐统计——让数据像风一样自由!(十)——关联研究全自动分析
  • AutoGen快速入门
  • v$lock 查找锁 locked objects ORA-54 dblink
  • Daily算法刷题【面试经典150题-2️⃣】
  • Ucloud技术支持问题
  • 调试 cuda kernel
  • OpenLayers常用控件 -- 章节九:比例尺控件教程
  • 李沐深度学习论文精读(一)AlexNet + ResNet
  • CMake构建C++项目,报错“CMake Error CMAKE_C_COMPILER not set, after EnableLanguage”
  • 2025最新超详细FreeRTOS入门教程:第五章 FreeRTOS信号量
  • 安卓逆向(二)相关问题及解决方案
  • 自学嵌入式第37天:MQTT协议
  • daily notes[11]
  • Qt中QProxyStyledrawControl函数4个参数的意义
  • AutoHotkey识别图片
  • 【数学建模】在烟雾导弹遮蔽模型中的实际参考文献
  • 快速了解word2vec模型
  • 关于高并发的一连串问题分析(未完成)
  • Ansible Playbook 核心配置实操指南:主机清单引用、并行执行与模块化组织
  • 2025年金融专业人士职业认证发展路径分析
  • NVM 使用指南(Node Version Manager)
  • 2025年体制内职业发展相关认证选择指南
  • 电脑提速之关于Edge优化
  • 图像纹理相似度评价——Gabor变换
  • [光学原理与应用-463]:波动光学 - AOM的0级光与1级光