shell脚本grep指令sed指令awk指令

面试题:grep、sed、awk有何区别?

  • grep 用于查找特定内容,适合快速过滤日志或配置文件。

  • sed 用于修改编辑文本,非常适合批量替换或删除操作。

  • awk 更强大,适用于列状数据的处理,能够提取字段、统计数据或进行数学计算。

在运维工作中,我会根据不同的需求选择合适的工具:当需要简单查找时用 grep,批量修改文件时用 sed,处理复杂的日志或统计数据时使用 awk。

grep

grep主要作用:过滤来自一个文件或标准输入匹配模式内容。

除了 grep 外,还有 egrep。egrep 是 grep 的扩展,相当于 grep -E。

基本语法:grep OPTION... PATTERN FILE...

|----------------------|--------------------------------|
| 支持的正则 | 描述 |
| -E,--extended-regexp | 模式是扩展正则表达式(ERE) => 字符簇、()、|或 |
| -P,--perl-regexp | 模式是Perl正则表达式 => \d、\w、\s |
| -i,--ignore-case | 忽略大小写 |
| -w,--word-regexp | 模式匹配整个单词--- 精准匹配单词 |
| -v,--invert-match | 打印不匹配的行 传说中的取反 |

|--------------------|----------|
| 输出控制 | 描述 |
| -n,--line-number | 打印行号 |
| -h,--no-filename | 不输出文件名 |
| -o,--only-matching | 只打印匹配的内容 |
| -r,--recursive | 递归目录 |
| -c,--count | 统计匹配行数 |

sed

sed = 流编辑器(Stream Editor),核心作用:批量修改、替换、删除、截取文本,主打行级文本编辑,不用打开文件,命令行直接处理

复制代码
sed [选项] '操作' 文件名
# 或 管道用法
命令 | sed '操作'
  • -n:只输出匹配 / 处理过的行(默认打印所有行)
  • -i:直接修改原文件(谨慎使用!)
  • -e:执行多个编辑指令

替换 s/旧/新/

复制代码
s/原字符串/新字符串/

# 把每行第一个 a 换成 b
sed 's/a/b/' test.txt

# 全局替换(整行所有 a 都换,加 g)
sed 's/a/b/g' test.txt

# 带 / 路径替换,改用 # 当分隔符(避免冲突)
sed 's#/usr#/home#g' test.txt

打印指定行(搭配 -n)

复制代码
# 只打印第 3 行
sed -n '3p' test.txt

# 打印 2~5 行
sed -n '2,5p' test.txt

# 匹配包含 root 的行并打印
sed -n '/root/p' test.txt

删除行(d = delete)

不加 -i 只预览,加 -i 才真删文件

复制代码
# 删除第 2 行
sed '2d' test.txt

# 删除空行
sed '/^$/d' test.txt

# 删除包含 # 注释的行
sed '/#/d' test.txt

插入 / 追加文本

  • i:行前插入

  • a:行后追加

    在第 1 行前面加内容

    sed '1i 开头文字' test.txt

    在最后一行后面加内容

    sed '$a 结尾文字' test.txt

    全局替换,并直接改原文件

    sed -i 's/old/new/g' test.txt

awk

复制代码
awk [选项] '模式{动作}'  文件名

常见选项NR ( Number of Record )当前处理的行号

常见选项NF (Number of Field) 当前行的字段总数

$0 当前行的整行内容

**1 2 ...**当前行的第 1、第 2... 个字段

复制代码
# 打印第3行的所有字段数
awk 'NR==3{print NF}' test.txt

# 打印第1行和第5行
awk 'NR==1 || NR==5' test.txt

# 打印所有行号大于2的行
awk 'NR>2' test.txt

#需求:取出用户名和他的登录shell

复制代码
awk -F":" '{print $1,$NF}'  /etc/passwd
  • -F":":指定分隔符为冒号 : /etc/passwd 里的每一行都是用冒号分隔字段的。
  • {print $1,$NF}
    • $1:代表每行的第 1 个字段(用户名)
    • $NF:代表每行的最后一个字段(用户的默认 shell)
  • /etc/passwd:要处理的文件路径。

需求:取出整行内容,并显示行号

复制代码
awk '{print NR,$0}' /etc/passwd

awk记录行

NR 全称是 Number of Record,中文叫 "记录号 / 行号"

复制代码
#取 ifconfig ens160 的输出,交给 awk 处理,当读到第 2 行时,打印这一行的第 2 个字段(通常就是网卡的 IP 地址)
ifconfig ens160 | awk 'NR==2{print $2}'
  • NR:awk 处理文本时,每读一行,NR 的值就会 + 1,所以它代表当前正在处理的行号
  • NR==2:是一个条件判断(模式),意思是 "当行号等于第 2 行的时候"。
  • {print $2}:是满足条件时执行的动作,打印这一行的第 2 个字段。

awk模式与动作进阶

awk '$0~/正则表达式/'

以冒号为分隔符,截取/etc/passwd 里第五列(用户注释信息)是否包含字符串 shutdown

复制代码
awk -F":" '$5~/shutdown/' /etc/passwd

例子1,有一个文档里面显示如下

练习:显示姓Zhang的人的第二次捐款金额及她的名字

复制代码
awk -F"[ :]+" '$1~/^Zhang/{print $1$2,$(NF-1)}' awk.txt

练习:显示Xiaoyu的名字和ID号码,并以逗号隔开

复制代码
awk -F"[ :]+" '$2~/^Xiaoyu/{print $2","$3}' awk.txt

练习:显示所有以41开头的ID号码的人的全名和ID号码

复制代码
awk -F"[ :]+" '$3~/^41/{print $1$2$3}' awk.txt

练习:取出网卡ens33/ens160的ip地址

复制代码
ifconfig ens160 |sed -n '2p' |awk -F"[ ]+" '{print $3}'

练习:取出常用服务端口号 思路: linux下面服务与端口信息的对应表格在/etc/services里面,所以这道题要处理/etc/services文件

复制代码
awk -F"[ /]+" '$1~/^(ssh|https|ftp|rsync)$/{print $1,$2}' /etc/services|sort|uniq -c|sort -nr

BEGIN模式和END模式

BEGIN设置表头

复制代码
awk 'BEGIN{print "username","UID"}{print $1":"$3}' awk.txt

给变量赋值方便后续做运算

复制代码
echo |awk 'BEGIN{a=10}{print a}'

awk 'BEGIN{a=10;print a}'
  • awk 'BEGIN{a=10;print a}'

    • 只有 BEGIN 块,所以只会执行一次:① a=10 给变量赋初始值② print a 直接打印这个值
    • 结果就是输出 10,这里变量的作用是临时保存一个值,供当前步骤使用
  • echo | awk 'BEGIN{a=10}{print a}'

    • 执行流程分两步:① 先执行 BEGIN{a=10}:初始化变量 a10(只执行 1 次)② 再执行 {print a}:因为 echo 给了 1 行输入,所以主处理块会执行 1 次,打印 a 的值 10
    • 这里变量 a 的值,从 BEGIN传递到了后续的主处理块里。

END

  • 自动初始化 :awk 中未初始化的数字变量,默认值为 0,所以 i 一开始就是 0
  • 计数逻辑 :每遇到一个空行,i++ 就会让 i 加 1,记录空行的数量。
  • 结果输出END 块在所有行处理完后执行,此时 i 的值就是最终的空行总数

awk支持数学运算

查看cpu的使用率

复制代码
top -bn1 | awk -F"[ ,]+" 'NR==3{print $8}'

第3行第8列,以多个空格逗号分隔

计算1-100的和

复制代码
seq 100 > 100.txt 

$0整行内容 代表当前处理的一整行数据,不管这一行有多少字段,$0 都是完整的一行

$1第 1 个字段代表当前行按分隔符切分后的第一个字段,默认分隔符是空格 / 制表符

相关推荐
Shadow(⊙o⊙)1 小时前
信号2.0,深入信号三张表block pending handlers,core文件的使用,信号执行逻辑:CPU虚拟内存物理内存,时钟源,软中断。
linux·运维·服务器·开发语言·c++
深圳市晶科鑫实业有限公司1 小时前
AI服务器为何对低抖动差分晶振如此挑剔?
服务器·人工智能·单片机·物联网·车载系统·云计算·信息与通信
爱和冰阔落1 小时前
【MCP实战】从0写一个本地工具服务器:文件搜索、SQLite查询与安全边界
服务器·安全·sqlite
日取其半万世不竭1 小时前
Project Zomboid 服务器进不去?端口、MOD 和日志排查清单
运维·服务器
嵌入式修炼师1 小时前
搭建linux nfs服务远程调试环境
linux
不吃土豆的马铃薯1 小时前
高并发服务器数据库连接池设计详解
服务器·网络·数据库·c++·mysql
刚子编程1 小时前
从零开始:在 Windows 服务器上部署 Node.js 项目(小白实战教程)
服务器·nestjs·pm2·windowsserver·node.js部署·caddy反向代理
zhangrelay2 小时前
ROS2 Lyrical 入门+进阶+精通+……
linux·笔记·学习·机器人·课程设计
Shadow(⊙o⊙)2 小时前
C++进阶知识3.0
linux·服务器·开发语言·c++