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 程序执行前,模式
pattern和hold 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