grep和sed

grep和sed

文章目录

grep

擅长过滤,其功能是从文本文件或管道数据流中筛选匹配的行及数据。

模式选择和解释选项

bash 复制代码
[root@server ~ 09:32:25]# echo 'Is is the cost of of gasoline going up up?' | egrep '\s([a-z]+) \1'
Is is the cost of of gasoline going up up?

[root@server ~ 09:32:40]# echo 'Is is the cost of of gasoline going up up?' | egrep '\s([a-z]+)\s\1'
Is is the cost of of gasoline going up up?

[root@server ~ 09:37:38]# echo 'Is is the cost of of of gasoline going up up?' | egrep '\s([a-z]+\s+)\1{1,}'
Is is the cost of of of gasoline going up up?

[root@server ~ 09:39:54]# cat words | egrep '(dog){3}'
dogdogdog

[root@server ~ 09:51:29]# cat words
cat
category
acat
concatenate
cbt
c1t
cCt
c-t
c.t
dog
hello cat kitty
dg
doog
dooog
doooog
dogdog
dogdogdog

[root@server ~ 09:51:43]# cat words | egrep 'cat|dog'
cat
category
acat
concatenate
dog
hello cat kitty
dogdog
dogdogdog

[root@server ~ 09:51:55]# cat words | egrep 'ca(t|d)og'

[root@server ~ 09:52:04]# echo -e 'cat\ndog' > pattens_file

#从文件读取
[root@server ~ 09:52:19]# cat words | grep -f pattens_file 
cat
category
acat
concatenate
dog
hello cat kitty
dogdog
dogdogdog

#忽略大小写匹配
[root@server ~ 09:52:37]# cat words | grep -i 'cBt'
cbt

#匹配整个单词
[root@server ~ 09:52:55]# cat words | grep -w 'cat'
cat
hello cat kitty

#匹配整行
[root@server ~ 09:53:02]# cat words | grep -x 'cat'
cat

输出控制选项

bash 复制代码
#反向匹配
[root@server ~ 10:33:12]# cat words | egrep -v '^d|^c'
acat
hello cat kitty

[root@server ~ 10:33:27]# egrep -v '^\s*#|^$' /etc/profile

[root@server ~ 10:34:05]# cat words | grep 'dog'
dog
dogdog
dogdogdog

#控制最大匹配数目
[root@server ~ 10:34:21]# cat words | grep -m2 'dog'
dog
dogdog

#显示匹配到项目的数量
[root@server ~ 10:34:25]# cat words | grep -c 'dog'
3

#显示匹配项目的行号
[root@server ~ 10:34:35]# cat words | grep -n 'dog'
10:dog
16:dogdog
17:dogdogdog

#only,只显示匹配到的内容
[root@server ~ 10:35:10]# cat words | grep -o 'dog'

#不显示任何正常输出
[root@server ~ 10:35:27]# cat words | egrep -q 'dog'
[root@server ~ 10:35:41]# echo $?
0

[root@server ~ 10:35:50]# cat words | egrep -q 'dog11'
[root@server ~ 10:35:58]# echo $?
1

[root@server ~ 10:36:49]# su - demo01
[demo01@server ~ 10:37:36]$ grep '^SELINUX=' /etc/shadow
grep: /etc/shadow: Permission denied

#不显示任何错误输出
[demo01@server ~ 10:37:45]$ grep -s '^SELINUX=' /etc/shadow

查找文件选项

bash 复制代码
#递归匹配目录
[root@server ~ 10:59:12]# grep -r '^SELINUX=' -s /etc/
/etc/selinux/config:SELINUX=disabled

#递归匹配目录,跟随软链接
[root@server ~ 10:59:28]# grep -R '^SELINUX=' -s /etc/
/etc/sysconfig/selinux:SELINUX=disabled
/etc/selinux/config:SELINUX=disabled

#不显示匹配项目所在文件的文件名
[root@server ~ 10:59:44]# grep -R '^SELINUX=' -s /etc/ -h
SELINUX=disabled
SELINUX=disabled

#显示匹配项目所在文件的文件名,默认
[root@server ~ 11:00:06]# grep -R '^SELINUX=' -s /etc/ -H
/etc/sysconfig/selinux:SELINUX=disabled
/etc/selinux/config:SELINUX=disabled

#对目录匹配时,只显示那些包含匹配模式的文件的名称
[root@server ~ 11:00:11]# grep -R '^SELINUX=' -s /etc/ -l
/etc/sysconfig/selinux
/etc/selinux/config

#只显示那些不包含匹配模式的文件的名称
[root@server ~ 11:00:17]# grep -R '^SELINUX=' -s /etc/ -L

输出内容控制选项

bash 复制代码
#显示匹配项目本身,以及前多少行
[root@server ~ 11:00:29]# ip addr | grep '10.1.8.10' -B2
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e3:88:ca brd ff:ff:ff:ff:ff:ff
    inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
    
#显示匹配项目本身,以及后多少行    
[root@server ~ 11:01:06]# ip addr | grep '10.1.8.10' -A2
    inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee3:88ca/64 scope link 
    
#显示匹配项目本身,以及前后多少行    
[root@server ~ 11:01:14]# ip addr | grep '10.1.8.10' -C2
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e3:88:ca brd ff:ff:ff:ff:ff:ff
    inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee3:88ca/64 scope link 

sed

一种非交互式的流编辑器,擅长修改文本。

注意事项

  • pattern space 空间是 sed 在内存中开辟的一个私有的存储区域。内存的特性,会导致关闭命令行或关机数据就消失。

  • 默认情况下,sed 命令只会处理 pattern space 空间中的数据,且并不会将处理后的数据保存到源文件中。也就是说,sed 默认并不会修改源文件。

    但 有一种方式用于修改 源文件就是传递 -i

  • sed 还在内存上开辟了另一个私有的空间 hold space 用于保存处理后的数据以供以后检索。

  • sed 程序执行前,模式 patternhold space 空间都是空的。

  • 如果我们没有传递任何输入文件,sed 默认会从 标准输入 中读取数据。

  • sed 可以指定只处理输入数据中的行范围。默认情况下是全部行,因此会依次处理每一行。

bash 复制代码
[root@server ~ 11:26:30]# sed '' data.txt
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome

[root@server ~ 11:27:02]# cat data.txt
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome

# ctrl + d 退出
[root@server ~ 11:28:10]# sed ''
xxx
xxx

[root@server ~ 11:28:31]# sed -e '1d' -e '2d' data.txt 
I am a Superman
I am so handsome

[root@server ~ 11:29:39]# cat data.txt 
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome

[root@server ~ 11:29:45]# sed -e '1d;2d' data.txt 
I am a Superman
I am so handsome

#生成脚本
[root@server ~ 11:29:56]# echo -e "1d\n2d\n5d" > scripts
[root@server ~ 11:31:48]# cat scripts 
1d
2d
5d

#读取脚本运行
[root@server ~ 11:31:51]# sed -f scripts data.txt 
I am a Superman
I am so handsome

[root@server ~ 11:31:58]# sed -n '' data.txt 

# 打印第一行记录
[root@server ~ 11:32:25]# sed -n '1p' data.txt 
I am studing sed

[root@server ~ 11:32:31]# sed '1p' data.txt 
I am studing sed
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome

sed 行寻址

bash 复制代码
[root@server ~ 13:28:10]# echo 'This is 1    
> This is 2    
> This is 3
> This is 4
> This is 5 ' > test

#打印所有行
[root@server ~ 13:36:47]# cat test | sed ''
This is 1    
This is 2    
This is 3
This is 4
This is 5 

[root@server ~ 13:36:56]# cat test | sed -n ''

[root@server ~ 13:37:04]# cat test | sed -n 'p'
This is 1    
This is 2    
This is 3
This is 4
This is 5 

#打印特定行
[root@server ~ 13:37:07]# cat test | sed -n '1p'
This is 1    

[root@server ~ 13:37:37]# cat test | sed -n '$p'
This is 5 

[root@server ~ 13:37:48]# cat test | sed -n '1,2p'
This is 1    
This is 2    

[root@server ~ 13:37:56]# cat test | sed '1,2p'
This is 1    
This is 1    
This is 2    
This is 2    
This is 3
This is 4
This is 5 

#连续输出
[root@server ~ 13:38:21]# cat test | sed -n '1,+2p'
This is 1    
This is 2    
This is 3

#隔行输出
[root@server ~ 13:38:42]# cat test | sed -n '1~2p'
This is 1    
This is 3
This is 5 

[root@server ~ 13:38:57]# cat test | sed -n '1~3p'
This is 1    
This is 4

sed 模式寻址

bash 复制代码
#准备环境
[root@server ~ 13:39:19]# cat << 'EOF' > ~/test
> root:x:0:0:root:/root:/bin/bash
> bin:x:1:1:bin:/bin:/bin/false
> daemon:x:2:2:daemon:/sbin:/bin/false
> mail:x:8:12:mail:/var/spool/mail:/bin/false
> ftp:x:14:11:ftp:/home/ftp:/bin/false
> &nobody:$:99:99:nobody:/:/bin/false
> zhangy:x:1000:100:,,,:/home/zhangy:/bin/bash
> http:x:33:33::/srv/http:/bin/false
> dbus:x:81:81:System message bus:/:/bin/false
> hal:x:82:82:HAL daemon:/:/bin/false
> mysql:x:89:89::/var/lib/mysql:/bin/false
> aaa:x:1001:1001::/home/aaa:/bin/bash
> ba:x:1002:1002::/home/zhangy:/bin/bash
> test:x:1003:1003::/home/test:/bin/bash
> @zhangying:*:1004:1004::/home/test:/bin/bash
> policykit:x:102:1005:Po
> EOF

#打印含有字符串zhang的行
[root@server ~ 13:40:22]# cat test | sed -n '/zhang/p'
zhangy:x:1000:100:,,,:/home/zhangy:/bin/bash
ba:x:1002:1002::/home/zhangy:/bin/bash
@zhangying:*:1004:1004::/home/test:/bin/bash

[root@server ~ 13:40:41]# cat test | sed -n '/^root/,/^mail/p'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
mail:x:8:12:mail:/var/spool/mail:/bin/false

#打印root开头的行到第三行
[root@server ~ 13:41:54]# cat test | sed -n '/^root/,3p'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false

#打印root开头的行到最后一行
[root@server ~ 13:42:33]# cat test | sed -n '/^root/,$p'

sed 子命令

  • p,打印模式空间所有记录。
  • P,打印模式空间第一行记录。
  • p 命令仅从 模式缓冲区 中打印行,也就是该行不会发送到输出流,原始文件保持不变。
  • n,提前读取下一行,覆盖模型空间之前读取的行。模型空间之前读取的行并没有删除,依然打印至标准输出,除非使用-n选项指明不打印。
  • N,追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有\n换行符。
bash 复制代码
[root@server ~ 13:43:11]# echo 'This is 1    
> This is 2    
> This is 3'
This is 1    
This is 2    
This is 3

#打印前2行
[root@server ~ 14:10:19]# echo 'This is 1    
This is 2    
This is 3'| sed -n '1{N;p}'
This is 1    
This is 2    

[root@server ~ 14:10:51]# echo 'This is 1    
This is 2    
This is 3'| sed -n '1{N;P}'
This is 1    

#打印偶数行内容
[root@server ~ 14:11:05]# echo 'This is 1
> This is 2
> This is 3
> This is 4
> This is 5' | sed -n 'n;p'
This is 2
This is 4

[root@server ~ 14:11:42]# echo 'This is 1
This is 2
This is 3
This is 4
This is 5' | sed -n 'N;p'
This is 1
This is 2
This is 3
This is 4

#替换
[root@server ~ 14:11:54]# sed 's/root/tankzhang/' test | grep tankzhang
tankzhang:x:0:0:root:/root:/bin/bash

#全部替换
[root@server ~ 14:15:00]# sed 's/root/tankzhang/g' test | grep tankzhang
tankzhang:x:0:0:tankzhang:/tankzhang:/bin/bash

[root@server ~ 14:16:32]# sed -n 's/root/tankzhang/p' test
tankzhang:x:0:0:root:/root:/bin/bash

[root@server ~ 14:17:03]# sed -n 's/root/tankzhang/gp' test
tankzhang:x:0:0:tankzhang:/tankzhang:/bin/bash

#在第二行到第八行之间替换
[root@server ~ 14:17:08]# sed -ne '2,8s/^zhang/ying/gp' test
yingy:x:1000:100:,,,:/home/zhangy:/bin/bash

#从以zhang开头的行开始,到匹配Po的行结束,在他们之间进行替换
[root@server ~ 14:19:32]# sed -ne '/^zhang/,/Po/ s/zhang/ying/gp' test
yingy:x:1000:100:,,,:/home/yingy:/bin/bash
ba:x:1002:1002::/home/yingy:/bin/bash
@yingying:*:1004:1004::/home/test:/bin/bash

#分隔符可以自定义
[root@server ~ 14:21:08]# sed -n 's@root@hello@gp' test 
hello:x:0:0:hello:/hello:/bin/bash

插入

bash 复制代码
#a 在匹配行下面插入新行
[root@server ~ 15:17:04]# sed -nr '/root/a====iiii====\nroot/p' test 

#i 在匹配行上面插入新行
[root@server ~ 15:18:18]# sed -nr '/root/i====iiii====\nroot/p' test 

#用s命令实现
[root@server ~ 15:19:34]# sed -nr 's/root(.*)/root\1\n====iiii====/p' test 
root:x:0:0:root:/root:/bin/bash
====iiii====

[root@server ~ 15:20:39]# sed -nr 's/root(.*)/root\1\n====aaaa====/p' test 
root:x:0:0:root:/root:/bin/bash
====aaaa====

[root@server ~ 15:22:17]# sed -nr 's/^root/haharoot/p' test 
haharoot:x:0:0:root:/root:/bin/bash

[root@server ~ 15:23:08]# sed -nr 's/^root(.*)/root\1heihei/p' test 
root:x:0:0:root:/root:/bin/bashheihei

[root@server ~ 15:23:51]# sed -nr 's/root/demo-root/gp' test 
demo-root:x:0:0:demo-root:/demo-root:/bin/bash

[root@server ~ 15:24:51]# sed -nr 's/root/root-demo/gp' test 
root-demo:x:0:0:root-demo:/root-demo:/bin/bash

[root@server ~ 15:25:16]# sed -nr 's/^root/ /p' test 
 :x:0:0:root:/root:/bin/bash

删除

bash 复制代码
#删除1,14行
sed -e '1,14d' test

#删除4以后的行,包括第4行
sed -e '4,$d' test

#删除包括false的行,或者包括bash的行
sed -e '/\(false\|bash\)/d' test

#或者
sed -re '/(false|bash)/d' test

#删除从匹配root的行,到匹配以test开头的行,中间的行
sed -e '/root/,/^test/d' test

#使用 s 命令实现

#删除特定行
sed -r 's/^root(.*)$//;/^$/d' test

#删除特定字符串
sed -nr 's/^root//gp' test

其他

bash 复制代码
sed '=' test

sed '=' test| sed 'N;s/\n/:/'

# 将小写字母s和i转换成大写字母S和I
echo 'This is 1    
This is 2    
This is 3    
This is 4    
This is 5' | sed 'y/si/SI/'

#读取
vim test2
=============
-------------
+++++++++++++

sed -e '/^root/r test2' test
root:x:0:0:root:/root:/bin/bash
=============
-------------
+++++++++++++
bin:x:1:1:bin:/bin:/bin/false
......

#写入
sed -n '/^root/w test3' test

cat test3
root:x:0:0:root:/root:/bin/bash

sed -r 's/^root(.*)KaTeX parse error: Expected group after '^' at position 5: //;/^̲/d' test

#删除特定字符串

sed -nr 's/^root//gp' test

复制代码
## 其他

```bash
sed '=' test

sed '=' test| sed 'N;s/\n/:/'

# 将小写字母s和i转换成大写字母S和I
echo 'This is 1    
This is 2    
This is 3    
This is 4    
This is 5' | sed 'y/si/SI/'

#读取
vim test2
=============
-------------
+++++++++++++

sed -e '/^root/r test2' test
root:x:0:0:root:/root:/bin/bash
=============
-------------
+++++++++++++
bin:x:1:1:bin:/bin:/bin/false
......

#写入
sed -n '/^root/w test3' test

cat test3
root:x:0:0:root:/root:/bin/bash
相关推荐
代码匠心19 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong21 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode21 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419421 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo21 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭21 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木21 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮21 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati1 天前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉1 天前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain