Linux三剑客之sed命令

今天我们来学习下 shell 脚本中的sed命令。首先我们来看看 sed 的工作流程,它可以分为以下几步:

我们看到先是读入到一个模式空间中,然后再进行输出。下来我们来看看 sed 命令的基本语法,它的命令格式为:sed [options] {sed-commands} {input-file};我们来看看

我们看到在我们用 sed 命令之后,输出了两遍它的内容。一个便是 example.txt 的内容,另一个是模式空间的内容。

下来我们来看看 sed 命令的 -n选项(--quit --silent);上面的 p 命令是指 print。我们要是想只输出一遍内容,那么我们就得加 -n 选项了。我们在前面的 makefile 中学习过,-n 选项就和之前的静默执行的效果是一样的。我们只打印第一行,看看效果

我们看到是输出了这个效果。下来我们来看看如果想打印第一行至第三行的内容呢

打印 Jason 所在行,如下

打印 Jason 至 Jane 所在的行

打印以 103 开头的行

打印以 Manager 结尾的行

以数字开头,而且是连续重复三次

每隔一行打印一次

我们看到 sed 命令的 -n 选项如上所示。下来我们来看看 sed 的** d 命令(delete**),删除 103 字符串所在的行,sed '/103/ d' example.txt

我们看到在 sed 命令中就删除了 103 行的内容,而在 example.txt 中也还是全部在,由此我们可以看出,sed 命令的模式空间确实是存在的。

下面我们来看看更多的 sed 选项,-f从文件中读入命令。新建 cmd.sed 命令文件,文件内容如下:/Jane/ p

我们看到 105 行 Jane 内容生成了两行。那么我们可以在命令文件中写多个命令,-e 选项执行多个命令,我们来打印 Jason 和 Jane 所在的行

我们看到先打印了 Jason 行,接着输出了 Jane 行。那么它是在里面怎么执行的呢?先是寻找 Jane 行,找到第五行然后执行,接着循环执行到 Jason 行,再接着输出。

下来我们来看看替换命令的格式:sed '[address-range|pattern-range] s/originalstring/replacement-string/[substitute-flags]' inputfile

我们来解释下上面格式中的相关东西,address-range:地址列表,表示从哪个地方开始执行,如:1,3 表示第一行到第 3 行;pattern-range:样式列表,表示从哪个样式匹配串开始。如:/Jane/,表示从行中包含字符串 Jane 的行开始执行,[ ]中的都是可选的 ;s:表示要执行替换命令(substitute);originalstring:需要被替换的字符串 ;replacement-string:替换后的字符串;substitute-flags:可选替换标志符。

下来我们基于上面创建的文本内容进行演示说明。

1、address-range 和 pattern-range
a> 把第一行的 John 替换成 guozi 字符串

**b> 把第二行至第五行的 Manager 替换成 guozi


c> 把 John 所以字符串行当中的 CEO 替换成 XXX

d> 从第四行而且包含字符串 Ram 的行中,把 Developer 字符串替换成 XXX

e> 如果没有 address-range 和 pattern-range,那么就会把每一行碰到的第一个匹配字符串给替换掉

我们看到只替换了第一个 1,而 101 中的后面的一个1 并没有替换掉,我们接着往下学习。

2、substitute-flags
a> 全局标志 g(globe)
全局标志会把遇到的所有的满足条件的字符串给替换掉

b> 数字标志 1,2,3

把要匹配串中的第 2 个符合条件的匹配串替换成我们想要的字符串

c> p(print)标志

d> 写标志 w(write)

        把每一行碰到第一个字符串 John 替换成 guozi 字符串,并写入 output.txt 中 

[图片上传失败...(image-35da08-1612668511731)]

e> 敏感标志 i(ignore flag)

忽略大小写,把文本当中所有包含 jason 字符串的行替换成 AAAA 字符串

我们看到在前面没加 i 之前,它是没进行替换的。但是在加上 i 之后,它已经替换了。

f> 联合使用标志

可以使用多个标志来对字符串进行替换并保存

3、替换命令定界符

格式 1:sed ‘s///’ example.txt

格式 2:sed ‘s@@@’ example.txt

用处:使用合理的定界符可以方便的阅读我们的程序代码。

我们看到在使用三种符号的效果是一样的,在有时有路径的情况下,用 @ 符号看起来比较好。

4、强大的& -- 样式匹配
将 origin-string 替换到 replace-string 当中

我们看到将 John 字符串直接加上 [ ]。需求:将开头为三位数字的外面再加一层{ } [图片上传失败...(image-3e3834-1612668511731)]

我们看到直接在三个数字外面加上 { }。下来我们来看看一个选项 i,它是什么作用呢?它的作用是直接替换文本内容,如下

我们看到 example.txt 的文本内容是直接被替换了。那么我们下面有个需求:将上面文本的前三位数截取出来,并加上大括号,去掉后面的全部内容,如下

解法一:sed 's/(^[0-9]),./{\1}/g' example.txt,以数字开头,然后将后面的全部替换为空,再用标签 1 来进行 { } 的替换

解法二:sed 's/([^,])./{\1}/g' example.txt,以逗号开头,然后将后面的全部替换为空,再用标签 1 来进行 { } 的替换

我们再来看看 sed 其他示例的讲解

a> 截取网卡 IP 的地址

解法一:使用 cut 命令

我们使用 grep 进行 inet addr 的查找,查找到信息后,再使用 cut 命令进行截断。我们来 man cut,看看 cut 命令的 -d 和 -f 选项是什么意思

我们在命令中使用 -d 来将冒号和空格替换为空,再用 -f 选项来保留第一段或者是第二段内容。

解法二:sed 命令

我们看到有三种写法,第一种是利用了 -e 可以将多个 sed 命令联合起来使用;第二种是以非数字开头的将它替换为空,再将以数字开头的后面全部去除掉;第三种则是替换数字前面,再找寻三段数字,最后将后面全部替换为空。

b> 去除注释和空行

我们将 /etc/network/interfaces 拷贝至当前目录下,再将它里面的注释和空行全部删除掉。先是利用以 # 开头的全部替换为空,再以空格结尾的进行全部删除,因此达到最后的要求。效果如最后 cat 所示。

我们下来看看附加的 sed 命令。

1、使用 a 命令追加行(append)

格式:sed '[address] a the-line-to-append' input-file

示例:a> 在文本的第 2 行后追加一行

b> 在文本最后追加一行

c> 在文本匹配处增加多行

2、使用 i 命令插入行(insert)

格式:sed '[address] i the-line-to-insert' input-file

用法跟 a 命令类似,不同的是匹配地址所有行之前

3、使用 c 命令修改行

格式:sed '[address] c the-line-to-insert' input-file

4、使用 l 命令打印隐藏字符

格式:sed -n l input-file

我们看到在加 l 选项后,\t 和结尾符 $ 都打印出来了。

5、使用 = 命令打印行号

格式:sed = input-file

6、使用 y 命令作字符转换

格式: sed 'y/original-string/replace-string/' input-file

我们看到 y 选项是用于将 abced 这几个字符转换为 ABCDE。它的用途是:用于加密字符串

7、使用 q 命令终止执行

示例:sed '3 q' input-file 执行完第3行后终止

sed '/Anand/ q' input-file匹配到 Anand 行后退出

转载文章
shell 之 sed 命令(七)

你可能感兴趣的:(Linux三剑客之sed命令)