正则表达式三剑客之——grep和sed

目录

一.grep

1.1定义

1.2核心功能

1.3基本语法

1.4常用选项

二.sed

[2.1 定义](#2.1 定义)

[2.2 工作原理](#2.2 工作原理)

[2.3 基本语法](#2.3 基本语法)

2.3.1常用选项

2.3.2sed自身脚本语法

[1. 基本组成](#1. 基本组成)

[2. 地址](#2. 地址)

[3. 命令](#3. 命令)

[2.3.3 sed替换查找](#2.3.3 sed替换查找)

[1 基本语法](#1 基本语法)

2.sed替换查找的实例

3.分组+后向引用

[4 变量调用](#4 变量调用)

三.练习


一.grep

1.1定义

grep 是一个命令行工具,用于在文本文件中搜索指定的模式(通常是字符串或正则表达式),并输出匹配的行。

1.2核心功能

  1. 文本搜索:在文件中查找包含指定模式的行。
  2. 模式匹配:支持基本字符串匹配和正则表达式匹配。
  3. 灵活输出:可以输出匹配的行、行号、文件名,或者统计匹配的行数等。

1.3基本语法

复制代码
grep [选项]... 查找条件 目标文件
  • 查找条件:要搜索的字符串或正则表达式。
  • 目标文件:要搜索的文件(可以是多个文件)。
  • 选项 :用于控制 grep 的行为(如忽略大小写、递归搜索等)

1.4常用选项

选项 功能 示例
-i 忽略大小写匹配 grep -i "hello" file.txt(匹配 helloHelloHELLO 等)
-v 反向匹配,输出不包含模式的行 grep -v "hello" file.txt(输出不包含 hello 的行)
-r 递归搜索目录 grep -r "hello" /path/to/dir(在目录及其子目录中搜索)
-R 递归目录,但处理软链接 grep -R "hello" /path/to/dir(在 /path/to/dir 及其子目录中递归搜索 "hello",并跟随符号链接。)
-n 显示匹配行的行号 grep -n "hello" file.txt(输出匹配行及其行号)
-m 最多输出的匹配行数。 grep -m 3 "hello" file.txt(输出前 3 个匹配的行,然后停止搜索。
-c(count) 统计匹配的行数 grep -c "hello" file.txt(输出匹配 hello 的行数)
-E 使用扩展正则表达式(等同于 egrep
-F 不支持正则表达式,相当于fgrep
-w 匹配整个单词 grep -w "hello" file.txt(只匹配单词 hello,不匹配 helloworld
-o(--only-matching) 只输出匹配的部分,而不是整行 grep -o "hello" file.txt(只输出 hello,而不是整行)
-l 只显示包含匹配模式的文件名 grep -l "hello" *.txt(输出包含 hello 的文件名)
-L 只显示不包含匹配模式的文件名 grep -L "hello" *.txt(输出不包含 hello 的文件名)
-A 显示匹配行及其后若干行 grep -A 2 "hello" file.txt(输出匹配行及其后 2 行)
-B 显示匹配行及其前若干行 grep -B 2 "hello" file.txt(输出匹配行及其前 2 行)
-C 显示匹配行及其前后若干行 grep -C 2 "hello" file.txt(输出匹配行及其前后 2 行)
-e 指定多个模式 grep -e "hello" -e "world" file.txt(匹配 helloworld
-f 从文件中读取模式 grep -f patterns.txt file.txt(从 patterns.txt 中读取模式进行匹配)
-q 静默模式,不输出任何内容,仅通过退出状态码表示是否匹配 grep -q "hello" file.txt(匹配成功返回 0,失败返回 1)
--color=auto 高亮显示匹配的部分 grep --color=auto "hello" file.txt(匹配的 hello 会高亮显示)
-h 不显示文件名(当搜索多个文件时) grep -h "hello" file1.txt file2.txt(只输出匹配行,不显示文件名)
-H 显示文件名(默认行为,当搜索多个文件时) grep -H "hello" file1.txt file2.txt(输出匹配行及其文件名)
-s 忽略错误信息(如文件不存在) grep -s "hello" non_existent_file.txt(不显示错误信息)

二.sed

2.1 定义

sed 是一个非交互式的流编辑器,它从输入流(如文件或管道)中逐行读取文本,根据用户指定的命令对文本进行处理,然后将结果输出到标准输出(默认是终端)。sed 不会直接修改原始文件,除非明确指定。

2.2 工作原理

sed 的核心是逐行处理文本。它的工作流程如下:

  1. 读取一行:从输入流中读取一行文本,并将其存储在**模式空间(Pattern Space)**中。

  2. 应用命令:对模式空间中的文本应用用户指定的命令(如替换、删除、插入等)。

  3. 输出结果:将处理后的文本输出到标准输出。

  4. 循环处理:重复上述步骤,直到所有行都被处理完毕。

模式空间(Pattern Space)

  • 用于存储当前正在处理的行。
  • 所有的 sed 命令都是对模式空间中的文本进行操作。

2.3 基本语法

复制代码
sed [option]... 'script;script;...' [input  file...]
     选项         自身脚本语法         支持标准输入管道

2.3.1常用选项

选项 说明
-n 禁止自动输出,只打印被 p 命令处理的行。
-e 指定多个脚本命令。
-f FILE 从脚本文件中读取命令。
-i 直接修改文件内容(原地编辑)。
-r或-E 使用扩展正则表达式(默认是基本正则表达式)。
-s 将输入文件视为多个独立的文件处理。
-i.bak 备份文件并原处编辑

2.3.2sed自身脚本语法

1. 基本组成

sed 脚本由一系列命令组成,每个命令通常包括以下部分:

  1. 地址(可选):指定命令作用的目标行。

  2. 命令:定义要执行的操作。

  3. 参数(可选):命令所需的额外信息。

2. 地址

地址用于指定命令作用的目标行。可以是行号、正则表达式或范围。

地址类型 格式 说明
单行地址 指定命令作用于某一行。
n n 行(n 是行号,从 1 开始)。
$ 最后一行。
/模式/ 匹配正则表达式 模式 的行。
范围地址 指定命令作用于一个范围内的行。
起始行,结束行 起始行结束行 之间的行。
/模式1/,/模式2/ 从匹配 模式1 的行到匹配 模式2 的行。
起始行,+n 起始行 开始的 n 行。
起始行,~n 起始行 开始,每隔 n 行处理一次。
组合地址 通过逻辑组合多个地址,指定更复杂的目标行。
地址1;地址2 地址1地址2 都执行命令。
地址1,地址2! 对不在 地址1地址2 之间的行执行命令。
特殊地址 sed 提供了一些特殊地址,用于处理特定的行。
1~n 从第 1 行开始,每隔 n 行处理一次。
n~m 从第 n 行开始,每隔 m 行处理一次。
0,/模式/ 从第 1 行到匹配 模式 的行。
3. 命令
命令 说明
d 删除匹配的行。
p 打印匹配的行。
Ip 忽略大小写输出
! 模式空间中匹配行取反处理
i\ 将指定的文本插入到匹配到的行前面。
a\ 将指定的文本添加到匹配到的行后面。
c\ 替换行为单行或多行文本
r file 将文件内容插入到当前行后。
w file 保存模式,将当前行写入文件。
q 退出 sed 处理。
= 为模式空间中的行打印行号
i 在当前行前插入文本。
s 替换文本。(更详细的在下面sed替换查找中)
复制代码
1.sed '1d' file.txt
删除 file.txt 的第一行。

2.sed -n '/pattern/p' file.txt
只打印包含 pattern 的行。

3.sed -n '/pattern/Ip' file.txt
忽略大小写并打印包含 pattern 的行。

4.sed '/pattern/!d' file.txt
删除不包含 pattern 的行。

5.sed '/pattern/i\new line' file.txt
在包含 pattern 的行之前插入 new line。

6.sed '/pattern/a\new line' file.txt
在包含 pattern 的行之后追加 new line。

7.sed '/pattern/c\new line' file.txt
将包含 pattern 的行替换为 new line。

8.sed '/pattern/r otherfile.txt' file.txt
在包含 pattern 的行之后插入 otherfile.txt 的内容。

9.sed '/pattern/w output.txt' file.txt
将包含 pattern 的行写入 output.txt。

10.sed '/pattern/q' file.txt
在遇到包含 pattern 的行后退出。

11.sed '/pattern/=' file.txt
打印包含 pattern 的行的行号。

12.sed 's/old/new/' file.txt
将 old 替换为 new。

13.sed '/pattern/i\new line' file.txt
在包含 pattern 的行之前插入 new line。

14.sed 's/old/new/' file.txt
将 old 替换为 new。

2.3.3 sed替换查找

1 基本语法
复制代码
sed 's/要查找的内容/替换的内容/修饰符' 文件名 
# '/'为分隔符,可以用'@' 或者 '#'
# 要查找的内容可以用正则表达式 
# 替换的内容无法用正则表达式

# 修饰符 #
g 行内全局替换
p 显示替换成功的行
w   /PATH/FILE 将替换成功的行保存至文件中
I,i   忽略大小写
2.sed替换查找的实例
复制代码
示例 1:简单替换
将每行的第一个 foo 替换为 bar:
sed 's/foo/bar/' input.txt

示例 2:全局替换
将每行的所有 foo 替换为 bar:
sed 's/foo/bar/g' input.txt

示例 3:忽略大小写替换
将每行的所有 foo(忽略大小写)替换为 bar:
sed 's/foo/bar/gi' input.txt

示例 4:打印替换后的行
仅打印替换后的行:
sed -n 's/foo/bar/p' input.txt

示例 5:将替换后的行写入文件
将替换后的行写入 output.txt
sed 's/foo/bar/w output.txt' input.txt
3.分组+后向引用

1. 分组

分组是指用括号 () 将一部分正则表达式括起来,形成一个子表达式。分组的作用包括:

  1. 捕获匹配的文本:将括号内的内容作为一个整体匹配,并捕获结果。
  2. 应用量词 :对分组内的内容应用量词(如 *+? 等)。
  3. 逻辑分组:将多个字符或表达式作为一个整体处理。

2. 后向引用

后向引用是指在正则表达式中引用之前捕获的分组内容。在 sed 中,后向引用使用 \1\2\3 等表示,分别对应第 1 个、第 2 个、第 3 个分组。

复制代码
echo "hello world" | sed 's/\(hello\) \(world\)/\2 \1/'

\(hello\) 是第 1 个分组,捕获 hello。
\(world\) 是第 2 个分组,捕获 world。
\2 \1 表示将第 2 个分组和第 1 个分组交换位置。

#将hello world中的hello和world分组,并交换位置



echo "hello hello world world" | sed 's/\([a-z]\+\) \1/\1/g'

s/.../.../:sed 的替换命令,用于查找并替换文本。
\([a-z]\+\):
\(...\):分组,捕获括号内的内容。
[a-z]\+:匹配一个或多个小写字母。
整体表示捕获一个单词(由小写字母组成)。
\1:
\1:后向引用,引用第 1 个分组捕获的内容。
整体表示匹配一个空格后跟第 1 个分组捕获的单词。
/\1/:替换为第 1 个分组捕获的内容。
g:全局替换,替换所有匹配项。

#将连续重复的单词替换为单个单词
4 变量调用

sed允许使用变量来替代文本中的特定部分。

sed 中使用变量时,需要注意以下几点:

  1. 变量替换 :变量需要在 sed 脚本之外定义,并通过双引号 " 传递给 sed

  2. 特殊字符 :如果变量中包含特殊字符(如 /\ 等),需要对其进行转义。

  3. 单引号与双引号

    • 单引号 ':sed 脚本中的内容会被视为字面量,变量不会被替换。
    • 双引号 "sed 脚本中的变量会被替换为其值。

    示例 1:简单变量替换
    将文本中的 foo 替换为变量 var 的值: var="bar" echo "foo foo foo" | sed "s/foo/var/g"

    示例 2:变量中包含特殊字符
    如果变量中包含 /,需要对其进行转义:
    var="path/to/file"
    echo "Replace this: /path/to/file" | sed "s#/path/to/file#$var#g"
    输出:Replace this: path/to/file
    这里使用 # 作为分隔符,避免与 / 冲突。

    示例 3:多变量替换
    将文本中的 foo 和 bar 分别替换为变量 var1 和 var2 的值:
    var1="hello"
    var2="world"
    echo "foo bar" | sed "s/foo/var1/; s/bar/var2/"
    输出:hello world

    示例 4:变量作为查找模式
    使用变量作为查找模式:
    pattern="foo"
    echo "foo bar foo" | sed "s/$pattern/replaced/g"

三.练习

复制代码
1找出/etc/passwd 文件中root 开头的行
grep    "^root"   /etc/passwd


2找出/etc/passwd 含有root 的行
grep    "root"   /etc/passwd


3找出/etc/passwd 文件中 root开头或 mail 开头的行
grep   -e "^root"  -e "^mail"   /etc/passwd
grep    "^root|^mail"   /etc/passwd

4过滤出 /etc/passwd文件中已bin开头的行,并显示行号
grep   -n   "^bin"   /etc/passwd

5过滤掉/etc/passwd文件中 root开头的行
grep  -v  "^root"   /etc/passwd


6.在当前目录下所有.cc 的文件中找到含有"luckyboy"内容的文件:
find -type f -name '*.cc' | xargs grep -l "luckyboy"
find -type f -name '*.cc' -exec grep -l "luckyboy" {} \;
-l --file-with-matches # 列出文件内容符合指定的范本样式的文件名称
-r 递归查询

7.找出当前目录下包含127.0.0.1关键字的文件
grep '127.0.0.1' `find . -type f `
sed -n '/127.0.0.1/p' `find . -type f`
awk '/127.0.0.1/' `find . -type f`

8.删除或显示1.file 文件第3行到第7行的内容
删除:
sed -i '3,7d' 1.file  
awk '(NR>=3&&NR<=7)' 1.file  把第三行到第七行排除
显示:
sed -n '3,7p' 1.file
awk 'NR>=3 && NR<=7' 1.file

9.从文件1.file中提取第3行到第7行的内容
sed -n '3,7p' 1.file 
awk 'NR==3,NR==7' 1.file 
awk 'NR>=3 && NR<=7' 1.file 
head -7 1.file | tail -5

10.使用awk取出/etc/passwd第一列数据也就是取出用户名。
awk -F : '{print $1}' /etc/passwd
sed 's#:.*$##g' /etc/passwd

11.用命令行更改config.txt文件,把里面所有的"name"更改为"address"
sed -i 's#name#address#g' config.txt
vim config.txt
	:%s#name#address#g
awk '{gsub(/name/,""address)}1' config.txt

12.写出查询file.txt以abc结尾的行
grep 'abc$' file.txt
sed -n '/abc$/p' file.txt
awk '/abc$/' file.txt

13.删除file.txt文件中的空行
grep -v '^$' file.txt
sed '/^$/d' file.txt
awk '!/^$/' file.txt
文件中的空行可能是只有空格的行:
grep -v '^ *$' file.txt
sed -n '/^ *$/p' file.txt
awk '/^ *$/' file.txt

14.打印file.txt文件中的第10行
sed -n '10p' file.txt
head -10 file.txt| tail -1
awk 'NR=10' file.txt

15.删除/etc/fstab文件中所有以#开头的行,行首的#号及#后面的所有空白字符
sed -i '/^#/ s/^#[[:blank:]]*//' /etc/fstab

16.查找最后修改时间是3天前,后缀是*.log的文件并删除
find /tmp/ -type -f -mtime -3 -name "*.log" | xargs rm -f
find /tmp/ -type -f -mtime -3 -name "*.log" -exec rm -f {} \;
find /tmp/ -type f -mtime +3 -name '*.log' -exec rm {} +

\; -exec find 命令找出 1 个文件就把文件放在{}的位置
+;如果-exec后面使用+ find会把前面找到的所有文件1次性的放在{}所在位置

17.查找文件2.txt中1到20行之间,同时将"aaa"替换为"AAA","ddd"替换"DDD"
sed '1,20y/ad/AD/' 2.txt
sed -ne 's#a#A#g;s#d#D#g;1,20p' 2.txt 

18.使用sed命令打印出文件的第一行到第三行
sed -n '1,3p'  file.txt
awk 'NR>=1&&NR<=3' file.txt
head -3  file.txt

19.在/var/sync/log/cef_watchd-20080424.1og文件中查找大小写不敏感"mysql"字符串中的命令是:
grep -iw 'mysql' /var/sync/log/cef_watchd-20080424.1og

20.把data目录及其子目录下所有以扩展名.txt结尾的文件中包含oldgirl的字符串全部替换为oldboy.
sed -i 's#oldgirl#oldboy#g' `find /data/ -type f -name '*.txt'`

21.查看linux服务器ip的命令,同时只显示包含ip所在的行打印出来
ip a s ens33 | sed -n '3p' | sed -r 's#^.*t ([0-9].*)/.*$#\1#g'
ip a s ens33 | sed -n '3p' | awk '{print $2;}' | awk -F / '{print $1;}'
sed语法:-r  使用正则表达式 

22.用awk获取文件中第三行的倒数第二列字段
awk 'NR==3{print $(NF-1)}' file.txt

23.请用shell查询file1里面空行的所在行号
grep -n '^$' file.txt
awk '/^$/{print NR,$0}' file1.txt

24.显示file文件里匹配foo字串那行以及上下5行、显示foo及前5行、显示foo及后5行
grep -A5 'foo'	file.txt		后5行
grep -B5 'foo'  file.txt		前5行
grep -C5 'foo' 	file.txt		上下5行


25.查找file.log文件中的包含关键字"helloworld"的内容,及其上下两行的内容重定向保存到1.txt
grep -C2  'helloworld' file.log >> 5.txt

26.当前系统中没有任何文本编辑器(vi,emacs,vim,edit等),如何过滤掉注释行和空行查看/etc/ssh/sshd_config文件
sed -r '/^#|^$/d' /etc/ssh/sshd_config
awk '!/^$|^#/' /etc/ssh/sshd_config 

27.从a.log文件中提取包含"WARNING"或"FATAL",同时不包含"IGNOR"行,然后,提取以":"分割的第五个字段
awk -F:  '/WARNING|FATAL/&&!/IGNOR/{print $5}'

28.文件内容排序、文件行取唯一值的命令分别是
sort
uniq   除文件中的重复内容行


29.在每一行后增加一空行?
sed 'G' test.txt

30.在匹配regex的行之后插入一空行?
sed '/regex/G' text.txt

31.计算文件行数?
wc -l

32.sed将文件test中第50行中的haiwao改为haiwai?
sed '50s/haiwao/haiwai/' test

33.替换一个文件/etc/passwd里的这root:x:0:0:root:/root:/bin/bash一行第二个root为test?
sed '/root/s/:root:/:test:/' /etc/passwd

34.打印/etc/passwd的奇数行?
sed -n '1~2p' /etc/passwd
相关推荐
星雨流星天的笔记本4 分钟前
1、Linux操作系统下,ubuntu22.04版本切换中英文界面
linux·学习
极小狐5 分钟前
如何创建并使用极狐GitLab 部署令牌?
运维·git·ssh·gitlab·github
muxue17814 分钟前
centos 7 网络配置(2):ping命令出现问题
linux·网络·centos
唐僧洗头爱飘柔952733 分钟前
(云计算HCIP)HCIP全笔记(九)本篇介绍操作系统基础,内容包含:操作系统组成、分类和定义,Linux的特性结构和Linux版本分类
linux·笔记·华为云·云计算·hcip·openeuler·操作系统概述
电鱼智能的电小鱼1 小时前
EFISH-SBC-RK3588 —— 厘米级定位 × 旗舰算力 × 工业级可靠‌
linux·人工智能·嵌入式硬件·边缘计算
高峰君主1 小时前
全栈自动化:从零构建智能CI/CD流水线
运维·ci/cd·自动化
yuanlaile1 小时前
Go全栈_Golang、Gin实战、Gorm实战、Go_Socket、Redis、Elasticsearch、微服务、K8s、RabbitMQ全家桶
linux·redis·golang·k8s·rabbitmq·gin
程序员JerrySUN1 小时前
驱动开发硬核特训 · Day 22(上篇): 电源管理体系完整梳理:I2C、Regulator、PMIC与Power-Domain框架
linux·驱动开发·嵌入式硬件
IT运维爱好者2 小时前
Ubuntu 22.04.4操作系统初始化详细配置
linux·运维·服务器·ubuntu
樂5022 小时前
关于 Web 服务器的五个案例
linux·服务器·经验分享