shell脚本grep指令sed指令awk指令
2026/6/15 3:02:51 网站建设 项目流程

面试题: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 个字段代表当前行按分隔符切分后的第一个字段,默认分隔符是空格 / 制表符

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询