linux sed命令转义,Linux运维:grep与sed命令

  • Post author:
  • Post category:linux


grep命令

grep全面搜索正则表达式并把行打印出来,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。它的输出一般是打印在屏幕上。

Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

grep如何工作的?

grep 命令在一个或多个文件中查找某个字符模式。如果这个模式中包含空格,就必须用引号把它括起来。 grep 命令中,模式可以是一个被引号括括起来的字符串,也可以是单个词,位于模式之后所有的单词都被视为文件名。 grep 将输出发送到屏幕,它不会对输入文件进行任何修改或变化。

示例1:grep root /etc/passwd

说明:grep命令将在文件/etc/passwd中查找模式root。如果查找成功,文件中相应的行就会显示在屏幕上,返回状态为0。如果查找失败,就不会有任何输出,返回状态为1。如果文件不存在,屏幕会显示报错信息,返回状态为2。

$ grep root /etc/passwd123 # 文件不存在

grep: /etc/passwd123: 没有那个文件或目录

$ echo $?

2 # 状态值为2

$ grep lala /etc/passwd # 查找模式不匹配

$ echo $?

1 # 状态值为1

$ grep root /etc/passwd # 成功匹配

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

$ echo $?

0 # 状态值为0,成功匹配

grep命令的输入可以来自文件,也可以来自标准输入或者管道。

示例2:ps aux | grep docker

[root@moli-04 ~]# ps aux | grep docker

root 893 0.1 5.5 486428 55472 ? Ssl 11:33 0:02 /usr/bin/dockerd

root 986 0.0 2.9 384508 29544 ? Ssl 11:33 0:01 docker-containerd –config /var/run/docker/containerd/containerd.toml

root 1296 0.0 0.2 108964 2628 ? Sl 11:33 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.17.0.2 -container-port 5000

root 1301 0.0 0.2 7488 2676 ? Sl 11:33 0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/63683775af1b8dd27080dbf898619a3f50a17bf557ac0e133ab52310c84dbf5e -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc

root 1317 0.0 0.8 20272 8128 ? Ssl 11:33 0:00 registry serve /etc/docker/registry/config.yml

root 1404 0.0 0.0 112720 968 pts/0 R+ 12:00 0:00 grep –color=auto docker

ps aux命令的输入被送到grep,然后包含docker的行都被输出到屏幕上。

正则表达式

grep支持很多正则表达式元字符,以便用户更精确地定义查找模式。

下面列出grep支持的常用基本表达式:

字符

含义

a

匹配字母a

.

匹配任意一个字符

*

匹配前一个字符出现0次或多次

.*

匹配任意字符

[ ]

匹配集合中任意一个字符,括号中为一个集合

[x-y]

匹配连续的字符串范围

^

匹配字符的开头

$

匹配字符的结尾

[^]

匹配否点,对括号中的集合取反

\

匹配转义后的字符串

\{n,m\}

匹配前一个字符出现n到m次

\{n,\}

匹配前一个字符至少出现n次

\{n\}

匹配前一个字符出现n次

()

保存已匹配的字符串,最大存储9个,括号左右需要使用转义字符(这里不知道为什么显示不了…)

grep命令的常用选项

选项

说明

-A num

(A即after)显示匹配的行,并显示匹配行的后num行,num为数字

-B num

(B即before)除了显示匹配的行,还显示匹配行的前num行,num为数字

-C num

前后匹配(相当于-A和-B)除了显示匹配的行,还显示匹配行的前后num行

-n

在输出结果显示行号,行号是该行在原来文件里的行号,而不是输出结果的行号

-v

取反,输出与匹配模式相反的内容

-E

相当与egrep,后面的模式是扩展正则表达式(grep -E == egrep)

-o

只显示匹配内容,grep默认输出匹配内容的行,加上-o选项只输出匹配的模式

-d

当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。

-c

count统计,统计匹配结果的行数,有n行匹配就输出数字n

实例:

将/etc/passwd的前10行输出保存到/tmp/grep.txt,下面grep实例都用这个文本文件。

[root@moli-04 ~]$ head -n 10 /etc/passwd > /tmp/grep.txt

[root@moli-04 ~]$ cat /!$

cat //tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

示例1:查找特定字符串,显示行号

[root@moli-04 ~]$ grep -n “root” /tmp/grep.txt

1:root:x:0:0:root:/root:/bin/bash

10:operator:x:11:0:operator:/root:/sbin/nologin

示例2:取反,将不包含root的行输出,并显示行号

[root@moli-04 ~]$ grep -nv “root” /tmp/grep.txt

2:bin:x:1:1:bin:/bin:/sbin/nologin

3:daemon:x:2:2:daemon:/sbin:/sbin/nologin

4:adm:x:3:4:adm:/var/adm:/sbin/nologin

5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6:sync:x:5:0:sync:/sbin:/bin/sync

7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

8:halt:x:7:0:halt:/sbin:/sbin/halt

9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

示例3:-A,-B,-C的使用

[root@moli-04 ~]$ grep -A 1 root /tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

[root@moli-04 ~]$ grep -B 1 root /tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

[root@moli-04 ~]$ grep -C 1 root /tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

第一条命令输出包含root的行,并输出它的后一行。

第二条命令输出包含root的行,并输出它的前一行。

第三条命令输出包含rott的行,并输出它的前后一行。

示例4:-c统计行数,包含root的行有几行

[root@moli-04 ~]$ grep -c root /tmp/grep.txt

2

示例5:^,$的使用

# 匹配以r字母为开头的行

[root@moli-04 ~]$ grep ^r /tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

[root@moli-04 ~]#

# 匹配以nologin单词为结尾的行

[root@moli-04 ~]$ grep nologin$ /tmp/grep.txt

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

示例6:[]的使用

# 查找包含ost或者oot的行

[root@moli-04 ~]$ grep o[os]t /tmp/grep.txt

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

示例7:匹配包含数字和包含小写字母的行'[0-9]’和'[a-z]’

$ grep ‘[0-9]’ /tmp/grep.txt

$ grep ‘[a-z]’ /tmp/grep.txt

输出结果太长就不复制进来了,多多动手实践吧(=゚ω゚)。

示例8:正则表达式实践

test.txt文件内容如下,注意有空白行。

aaa

bbb

111

222

AAA

BBB

hell world

I love python

pppppython

匹配数字开头的行:

$ grep ‘^[0-9]’ test.txt

111

222

匹配小写字母开头的行:

$ grep ‘^[a-z]’ test.txt

aaa

bbb

hell world

pppppython

匹配空白行,这里-n显示行号显示空白行在第几行

$ grep -n ‘^$’ test.txt

7:

逻辑匹配或者‘|’,需要使用转义字符”

$ grep ‘111\|222’ test.txt # 匹配111或者222

111

222

并且,利用管道

$ grep ‘love’ test.txt | grep ‘python’ # 匹配带有love和python的行

I love python

匹配p字母出现至少4次

$ grep ‘p\{4,\}’ test.txt # 中括号左右需要使用转义字符\

pppppython

egrep扩展正则表达式

egrep 在 grep 的基础上增加了更多的元字符。但是 egrep 不允许使用(),\{\}.下面是egrep支持使用的正则表达式元字符(只列举新增的)。

字符

说明

+

匹配一个或多个前面的字符,至少一个

匹配0个或1个起那么的字符,只能0或者1

竖线

或者(这里竖线就用中文了,因为markdown表格的竖线转义不了…)

()

匹配正则集合

sed命令

sed 是一种新型的,非交互式的编辑器。它能执行与编辑器 vi 和 ex 相同的编辑任务。

sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。

sed 编辑器没有破坏性,它不会修改文件,除非使用 shell 重定向来保存输出结果。

默认情况下,所有的输出行都被打印到屏幕上。

sed工作流程

sed通过文件或者管道读取文件内容,但sed默认并不直接修改源文件,而是将读入的内容复制到缓冲区中,我们称之为模式空间,所有的指令操作都是在模式空间中进行的,然后sed根据对应的指令对模式空间内的内容进行处理并输出结果,默认输出至标准输出(屏幕)。

sed基本语法

用法:sed [选项] {脚本指令} [输入文件]

sed操作地址匹配

sed 命令在没有给定的位置时,默认会处理所有行;

sed支持下面几种地址类型;

示例

说明

number

指定输入文件的唯一行号

first~step

指定first开始,并指定操作步长为step。比如1~2,指定第一行、第三行、第五行…为操作地址。

$

匹配文件最后一行

/regexp/

通过正则表达式匹配操作地址,//中间是正则表达式

addr1.addr2

匹配从操作地址1到操作地址2的所有行

addr1,+N

匹配地址1以及后面的N行内容

sed常用选项

选项

说明

-n

静默输出,sed程序默认在所有脚本指令执行完毕后自动打印模式空间中的内容,该选项可以屏蔽自动打印

-e

允许多个脚本指令被执行,指令顺序会影响结果

-i

修改源文件的内容,慎用

-f

从文件中读取脚本指令,对编写自动脚本程序很实用

-r

让sef支持扩展正则表示式

sed常用指令

指令

说明

a

追加(在原先行后追加)

d

删除

c

更改

i

插入(在原先行前插入)

s

替换

l

打印(显示非打印字符)

L

打印(不显示非打印字符)

p

打印

w

保存至文件

部分指令详解

替换指令:s

使用格式:[address]s/pattern/replacement/flags

address是操作地址,s为替换指令,pattern需要替换的内容,replacement替换的新内容,flags标记。

flags有几种:

n 表示1-512之间的数字,对模式空间中指定模式的第n次出现进行替换,如有2个hello,替换第二个hello为world可以这样写s/hello/world/2

g 表示全局替换。比如把模式空间中所有的a替换成b,可以这样写s/a/b/g

p 打印模式空间的内容.默认情况下, sed 把输入行打印在屏幕上,选项-n 用于取消默认打印操纵。选项-n 和命令 p 同时出现时, sed 可打印选定的内容。

w file 将模式空间的内容写到文件file中

sed示例

sed.txt文件内容

$ cat sed.txt

ONBOOT=yes

IPADDR=192.168.30.6

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DNS=119.29.29.29

在第一行后面追加TYPE=Ethernet

$ sed ‘1a TYPE=Ethernet’ sed.txt

ONBOOT=yes

TYPE=Ethernet #追加项

IPADDR=192.168.30.6

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DNS=119.29.29.29

在第2行前面插入TYPE=Ethernet

$ sed ‘2i TYPE=Ethernet’ sed.txt

ONBOOT=yes

TYPE=Ethernet # 插入项

IPADDR=192.168.30.6

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DNS=119.29.29.29

全局替换yes为no

$ sed ‘s/yes/no/g’ sed.txt

ONBOOT=no # yes被替换为no

IPADDR=192.168.30.6

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DNS=119.29.29.29

删除第1,2行的内容

$ sed ‘1,2d’ sed.txt

# 1,2行没了

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DNS=119.29.29.29

匹配以DNS为开头的行,并在该行前插入DEVICE=ens33

$ sed ‘/^DNS/i DEVICE=ens33’ sed.txt

ONBOOT=yes

IPADDR=192.168.30.6

NETMASK=255.255.255.0

GATEWAY=192.168.30.2

DEVICE=ens33 # 插入的行,下一行是以DNS为开头

DNS=119.29.29.29

除了直接将操作指令写在命令行里,还可以将操作指令写在脚本里,然后使用sed -f读取指令。

创建脚本,内容如下

$ cat sed.sh

# 这个脚本的作用是打印文件的奇数行,需要配合-n选项使用

1~2p

-f读取指令

$ sed -f sed.sh -n sed.txt

ONBOOT=yes

NETMASK=255.255.255.0

DNS=119.29.29.29

当需要执行多个指令的时候,可以有几种方式。

$ sed -n ‘s/yes/no/;s/static/dhcp/p’ sed.txt #使用分号

$ sed -e ‘s/yes/no/’ -e ‘s/static/dhcp/’ sed.txt # 使用-e选项

$ sed ‘

>s/yes/no/

>s/static/dhcp/’ sed.txt

常见案例1:使用sed命令将文件带#的行删除

实际在修改配置文件的时候,配置文件带有大量的注释,通常以’#’为开头,于是可以将这些以#为开头的行删掉。

[root@moli-04 tmp]$ cat sed2.txt

#ajksshdja

jskdjks

#kjklasj

123

$ sed -i ‘/^#/d’ sed2.txt

[root@moli-04 tmp]$ cat sed2.txt

jskdjks

123

常见案例2:删除空白行与删除以数字开头的行

$ sed ‘/^$/d’ sed.txt

$ sed ‘/^[0-9]*/d’ sed.txt

常见案例3:查找网卡对应ip地址

$ ifconfig | grep -A1 ens33|grep inet|sed s/^.*inet//g | sed ‘s/netmask.*$//g’

192.168.30.6