• Sed案例2


    Sed案例2


    追加下一行

    多行Next(N)命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。模式空间最初的内容和新的输入行之间用换行符分隔。在模式空间中嵌入的换行符可以利用转义序列“ ”来匹配。在多行模式空间中,元字符“^”匹配空间中的第一个字条,而不匹配换行符后面的字符。同样,“$”只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符,在执行next命令之后,控制将被传递给脚本中的后续命令。

    Next命令与next命令不同,next输出模式空间的内容,然后读取新的输入行。next命令不创建多行模式空间。

    例如,我们假设想要将“Owner and Operator Guide”换成“lnstallation Guide”,但是我们发现它出现在文件中的两行上,“Operator”和“Guide”被分开了。

    //文本text内容如下
    [root@yqh ~]# cat text
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    
    //匹配以Operator结尾以及下行的Guide,合并成一行替换成Installation Guide
    [root@yqh ~]# sed '/Operator$/{N;s/Operator
    Guide/Installation Guide/g}' text
    Consult Section 3.1 in the Owner and Installation Guide for a description of the tape drives
    available on your system.
    

    $!N

    排除对最后一行($)执行Next命令。

    //文本text1内容如下
    [root@yqh ~]# cat text1
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    
    //除最后一行,匹配Section,将所在行的Operator
    Guide全局替换成Installation Guide
    [root@yqh ~]# sed '/Section/{$!N;s/Operator
    Guide/Installation Guide/g}' text1
    Consult Section 3.1 in the Owner and Installation Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Installation Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Installation Guide for a description of the tape drives
    available on your system.
    

    转换Interleaf 文件

    FrameMaker 和Interleaf 给出了WYSIWYG(所见即所得)技术发布包。它们两个都有能力读取和保存与普通二进制文件格式相对应的ASCII编码格式的文档内容。在这个例子中,我们将lnterleaf 文件转换成trooff ;然而,同一类型的脚本可以应用于将troff 编码的文件转换成Interleaf格式。这同样也适用于FrameMaker.它们两个都在文件中放置编码标签,由尖括号括起来。

    实例1:

    //文本text2内容如下
    [root@yqh ~]# cat text2
    <para>
    This is a test paragraph in Interleaf style ASCII. Another line
    in a paragraph. Yet another.
    <Figure Begin>
    v.11111110000001111110000
    1000001001000100000
    000
    <Figure End>
    <para>
    More lines of text to be found after the figure.
    These lines should print.
    
    //匹配以<Figure Begin>开头,以<Figure End>结尾的内容,将其写入fig.interleaf文件中,插入.FG
    <insert figure here>
    .FE内容,并删除匹配的内容
    [root@yqh ~]# sed '
    > /<Figure Begin>/,/<Figure End>/{
    > w fig.interleaf
    > /<Figure End>/i
    > .FG
    > <insert figure here>
    > .FE
    > d
    > }' text2
    <para>
    This is a test paragraph in Interleaf style ASCII. Another line
    in a paragraph. Yet another.
    .FG
    <insert figure here>
    .FE
    <para>
    More lines of text to be found after the figure.
    These lines should print.
    [root@yqh ~]# cat fig.interleaf 
    <Figure Begin>
    v.11111110000001111110000
    1000001001000100000
    000
    <Figure End>
    

    实例2:

    //文本text1内容如下
    [root@yqh ~]# cat text1
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    
    //匹配以Guide开头,以available结尾的内容,将其写入20210329文件中,插入Guide for a description of the tape drives
    available on your system.内容,并删除匹配的内容
    [root@yqh ~]# sed '
    > /^Guide/,/^available/{
    > w 20210329
    > /available/i
    > Guide for a description of the tape drives
    available on your system.
    > d
    > }' text1
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    [root@yqh ~]# cat 20210329
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    

    多行删除

    删除命令(d)删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端重新使用编辑方法。删除命令(D)稍微有些不同:它删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容。

    //文本text3内容如下
    [root@yqh ~]# cat text3
    This line is followed by 1 blank line.
    
    This line is followed by 2 blank line.
    
    
    This line is followed by 3 blank line.
    
    
    
    This line is followed by 4 blank line.
    
    
    
    
    This is the end.
    
    //匹配空行,并将它的下一行添加到模式空间合成一行,两行之间依然有换行符,匹配以
    开头
    结尾,如果匹配成功就删除,否则就不做操作
    [root@yqh ~]# sed '/^$/{N;/^
    $/d}' text3
    This line is followed by 1 blank line.
    
    This line is followed by 2 blank line.
    This line is followed by 3 blank line.
    
    This line is followed by 4 blank line.
    This is the end.
    
    
    [root@yqh ~]# sed '/^$/{N;/^
    $/D}' text3
    This line is followed by 1 blank line.
    
    This line is followed by 2 blank line.
    
    This line is followed by 3 blank line.
    
    This line is followed by 4 blank line.
    
    This is the end
    

    当有偶数个空行时,所有的空行都会被删除。仅当有奇数个空行时,有一行被保留下来。这是因为删除命令清除的是整个模式空间。一旦遇到第一个空行,就读入下一行,并且两行都被删除。如果遇到第三个空行,并且下一行不为空,那么删除命令就不会被执行,因此空行被输出。如果使用多行Delete命令(是D不是d),就能得到我们想要的结果。

    多行Delete命令完成工作的原因是,当遇到两个空行时,Delete命令只删除两个空行中的第一个。下一次遍历该脚本时,这个空行将导致另一行被读入模式空间。如果那行不为空,那么两行都输出,因此确保了输出一个空行。换句话说,当模式空间中有两个空行时、只有第一个空行被删除。当一个空行后面跟有文本时,模式空间可以正常输出。

    1


    多行打印

    多行打印(Print)命令与小写字母的print命令稍有不同。该命令输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出-n选项或#n抑制这个默认的动作)。因此,当默认的输出被抑制或者脚本中的控制流更改,以至不能到达脚本的底部时,需要使用打印命令(P或p) .Print命令经常出现在Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模式空间,但是一次只输出一行。这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。

    Next命令将一个新的输入行追加到模式空间的当前行。在替换命令应用于多行模式空间之后,模式空间的第一部分被Print命令输出,然后被Delete命令删除。这意味着当前被输出并且新的行成为当前行。Delete命令阻止脚本到达底部,这将输出两行并清除模式空间的内容。Delete命令让我们保护了模式空间的第二部分,并将控制转移动脚本的顶端,在顶端所有的编辑命令都可以被应用于一行。这些命令中有一个是Next命令,它将另一个新行读入模式空间。

    实例1:

    //text4内容如下
    [root@yqh ~]# cat text4
    Here are examples of the UNIX
    System. Where UNIX
    System appears, it should be the UNIX
    Operating System.
    
    [root@yqh ~]# sed '
    /UNIX$/{
    N
    /
    System/{
    s// Operating &/
    P
    D
    }}' text4
    Here are examples of the UNIX Operating 
    System. Where UNIX Operating 
    System appears, it should be the UNIX
    Operating System.
    

    实例2:

    //text5内容如下
    [root@yqh ~]# cat text5
    hello world runtime
    yqh, where runtime
    yqh, what runtime
    it yqh.
    
    [root@yqh ~]# sed '
    > /runtime$/{
    > N
    > /
    yqh/{
    > s// it &/
    > P
    > D
    > }}' text5
    hello world runtime it 
    yqh, where runtime it 
    yqh, what runtime
    it yqh.
    

    包含那一行

    模式空间是容纳当前输入行的缓冲区。还有-一个称为保持空间(hold space)的顶留(set-aside)缓冲区。模式空间的内容可以复制到保持空间,而且保持空间的内容也可以复制到模式空间。有一组命令用于在保持空间和模式空间之间移动数据。保持空间用于临时存储。单独的命令不能寻址保持空间或者更改它的内容。

    保持空间最常的用途是,当改变模式空间中的原始内容时,用于保留当前输入行的副本。影响模式空间的命令有:

    命令 缩写 功能
    Hold h 或 H 将模式空间的内容复制或追加到保持空间
    Get g 或 G 将保持空间的内容复制或追加到模式空间
    Exchange x 交换保持空间和模式空间的内容

    这些命令中的每一条都可以利用一个地址来指定一行或行范围。Hole(h,H)命令将数据移至保持空间、而get (g.G)命令将保持空间的数据移回到模式空间。同一命令的小写字母和大写字母之间的差别是,小字字母命令改写目的缓存区的内容,而大写字母命令追加缓存区的现有内容。

    Hole命令在保持空间的内容之后放置一个换行符,且后面跟随模式空间的内容(即使保持空间是空的,换行符也被追加到保持空间中)。Get命令模式空间的内容之后放置一个换行符,且后面跟随保持空间的内容。

    交换命令交换两个缓存区的内容,对两个缓存区没有副作用。

    //文本text6内容如下
    [root@yqh ~]# cat text6
    1
    2
    11
    22
    111
    222
    
    //这里的目的是颠倒以1开始的行和以2开始的行的顺序,将第一行复制到保持空间(它一直在那),这时清除模式空间,然后sed将第二行读入模式空间,并且将保持空间的行追加到模式空间的结尾
    [root@yqh ~]# sed '
    > /1/{
    > h
    > d
    > }
    > /2/{
    > G
    > }' text6
    2
    1
    22
    11
    222
    111
    
    [root@yqh ~]# sed '
    /1/{
    h
    d
    }
    /2/{
    g
    }' text6
    1
    11
    111
    

    匹配“1”的任何行都被复制到保持空间并且从模式空间删除,控制转移到脚本的顶端并且不打印那一行,当读取下一行时,它匹配模式“2”且将已经复制到保持空间的行追加到模式空间之后,然后两行都被打印出来,保存这两行中的第一行并且直到匹配第二行时才输出它。


    构建文本块

    保持空间可用于在输出行块之前收集它们,一些troff请求和宏是面向块的,这命令中必须包围文件块。通常在块开始处的代码用启用格式,而大块结尾处的代码用禁用格式。HTML编码的文档还包含许多面向块的结构。例如,“《p》”和“《/p》”分别用于开始和结束一个段落。输入文件包含由可变长度的行组成的段落,段落之间都有一个空行。因此,脚本必须将空行之前的所有行收集到保持空间。检索保持空间的内容并且用段落标签包围这些内容。

    //文本text7内容如下
    [root@yqh ~]# cat text7
    hello world
    hello runtime
    
    abc
    def
    
    123
    456
    
    end
    
    [root@yqh ~]# sed '
    > /^$/!{
    > H
    > d
    > }
    > /^$/{
    > x
    > s/^
    /<p>/
    > s/$/</p>/
    > G
    > }' text7
    <p>hello world
    hello runtime</p>
    
    <p>abc
    def</p>
    
    <p>123
    456</p>
    
    
  • 相关阅读:
    根据包路径输出类列表
    Logback配置
    接口的幂等性
    mock获取入参数并动态设置返回值
    linux,日志查找技巧
    scrapy 一些坑
    Pyinstaller打包附带DLL、图标和压缩EXE方法
    scrapy 爬虫教程
    买房
    Python: 在CSV文件中写入中文字符
  • 原文地址:https://www.cnblogs.com/yuqinghao/p/14594664.html
Copyright © 2020-2023  润新知