shell 之 sed 命令(七)

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

图片.png

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

图片.png

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

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

图片.png

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

图片.png

        打印 Jason 所在行,如下

图片.png

        打印 Jason 至 Jane 所在的行

图片.png

        打印以 103 开头的行

图片.png

        打印以 Manager 结尾的行

图片.png

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

图片.png

        每隔一行打印一次

图片.png

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

图片.png

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

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

图片.png

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

图片.png

        我们看到先打印了 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 字符串

图片.png 

            b> 把第二行至第五行的 Manager 替换成 guozi
图片.png

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

图片.png

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

图片.png

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

图片.png

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

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

图片.png

            b> 数字标志 1,2,3

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

图片.png

            c> p(print)标志

图片.png

            d> 写标志 w(write)

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

图片.png

            e> 敏感标志 i(ignore flag)

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

图片.png

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

            f> 联合使用标志

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

图片.png

        3、替换命令定界符

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

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

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

图片.png

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

        4、强大的& -- 样式匹配

        origin-string 替换到 replace-string 当中
图片.png

        我们看到将 John 字符串直接加上 [ ]。需求:将开头为三位数字的外面再加一层{ }
图片.png

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

图片.png

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

图片.png

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

图片.png

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

图片.png

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

        a> 截取网卡 IP 的地址

        解法一:使用 cut 命令

图片.png

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

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

        解法二:sed 命令

图片.png

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

        b> 去除注释和空行

图片.png

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

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

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

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

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

图片.png

        b> 在文本最后追加一行

图片.png

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

图片.png

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

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

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

图片.png

        3、使用 c 命令修改行

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

图片.png

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

            格式:sed -n l input-file

图片.png

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

        5、使用 = 命令打印行号

            格式:sed = input-file

图片.png

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

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

图片.png

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

        7、使用 q 命令终止执行

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

            sed '/Anand/ q' input-file匹配到 Anand 行后退出
图片.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章