• 掌握Sed命令



    带书签PDF版,喜欢的话,欢迎多提意见和建议,你的支持是血蝙蝠最大的前进动力!


    http://download.csdn.net/detail/challenge_c_plusplus/6480007


    Part0    Sed预备知识

    0.1 什么是Sed

            Sed即StreamEDitor中3个大写字母的组合,是一种“流编辑器”。所谓流编辑器,就是面向流的编辑器。所谓流就是应用程序的输入经过程序处理,然后输出到标准输出。通俗点说,sed就是一种通过输入流,比如文件、键盘的输入,然后处理,最终输出到标准输出(即屏幕)的一种文本编辑器。它是unix-like系统下的一个常用文本处理命令。

    0.2 Sed相关的正则表达式

           读者请注意,通常我们把grep和sed视为一组,因为它们都使用shell的基础正则表达式,我们把egrep和awk视为一组,它们可以使用扩展的正则表达式。这里我们只介绍sed相关的正则表达式,即shell基础正则表达式语法。先说明,不要担心学不会,因为非常简单!

    .        代表除去换行符以外的任意单个字符

    例1:c.t 可以代表cat,cut,c!t等等

    *       不同于通配符,代表重复*前边一个字符任意次,即0次或多次

    例2:hello_*world!代表helloworld!,或者hello_world!,或者hello__world!等等

    […]   代表它内部包括的字符的任意一个

    例3:a[1234]c代表a1c,或者a2c,或a3c,或a4c

    ^       放在正则表达式的开始处,代表一行的开始位置,放在[]中的开始处,代表不是[]中字符的任意字符

    例4:^a[^1234]c代表文本中某一行以axc三个字符开头,其中x为不是1234的任意字符

    $       放在正则表达式的结尾处,代表一行的结束

    例5:abc$ 代表文本中以abc结尾的文本行

    {n,m}    代表重复前边一个字符n到m次中的任何一种。变种有{n}重复前边一个字符n次,{n,}重复前边一个字符至少n次。

    例5:abc{2,3}代表abcc或者abccc

    <     代表一个单词的开始

    例6:<Hello代表包含以Hello开头的单词的行

    >     代表一个单词的结束

    例7:Hello>代表包含以Hello结尾的单词的行

    &      代表匹配内容

    例8:s/hello/[&]/g,会将文本中的hello都替换为[hello],其中&代表匹配的hello

         n是1-512的任意数字,代表前边第n个符合(…)的匹配

    例9:s/([1-9]*)abc([A-Z]*)/21/g表达式,会将123abcABC转换为ABC123,其中1代表([1-9*]], 2代表([A-Z]*)

    PartI    Sed基本原则

    1.1 Sed命令的作用规则

    1.      脚本文件中的所有命令会顺序作用于待处理文本中的每一行;

    2.      地址过滤作用可以使脚本中的命令只作用于与地址匹配的特定行;

    3.      原始文本文件不会被改变,被改变的是原始文件的一个备份,处理后的备份行会输出。

    1.2 模式空间(The Pattern Space or The Temporary Buffer)

           存放sed脚本命令处理的当前行,即当前处理行的备份,命令实际改变的是这份备份,最后输出的也是这份备份。

    1.3 Sed命令地址详解

    (四种地址情况) 其中,地址可以是“正则表达式、行号、行中部分文本信息”三种

    1.  无地址 脚本中命令作用于所有行,例如 d 删除所有行

    2.  一个地址 命令作用于与地址匹配的对应行,例如 1d删除第一行,2d删除第二行

    3.  逗号分隔的两个地址 命令作用于两个地址之间的所有行,例如1,/^$/d删除第一行到第一个空行之间的所有行

    4.  地址后直接跟!号,命令作用于所有与地址不匹配的行 例如1!d删除除第一行外的所有行

    1.4 大括号的使用

    作用:嵌套地址,组合命令。左大括号必须在一行的末尾,右大括号必须独立成行,大括号后边直接跟回车,不能有空格

    例1:删除1-5行中的空白行

    1,5{

             /^$/d

    }

    例2:从1-5行中删除含linux或unix的行

    1,5{

             /linux/d

             /unix/d

    }

    1.5 Sed应用场景

    1 同时编辑多个同类文件

    2 修改文件内容

    3 提取文件内容

    1.6 Sed命令的两种使用方式

    方式一:使用脚本文件,语法:sed [other options] –f script.sed file

    方式二:直接使用命令行,语法 sed [options] ‘command’ file

    Sed命令使用时,可以直接在命令行使用,将命令通过单引号括起来,也可以将命令按行写在一个文本文件中,然后使用Sed的-f选项来加载脚本文件中的Sed命令集合。

    1.6.1 命令行方式

             最简答的命令行方式,比如sed‘1d’ file,表示删除文本文件file中的第一行;

             复杂点的就是包含多个命令的情况,有三种解决方式:第一种,在一个单引号里使用分号分隔各个命令,比如sed ‘1d;5d;9d’ file,就是删除第1,5,9行文本;第二种,使用多个-e选项分隔各个命令,比如sed –e ‘1d’ –e ‘5d’ –e ‘9d’ file;第三种,使用换行符来分隔各个命令,比如,其中#代表shell的命令提示符,>代表键入回车后的提示符:

    # sed ‘1d  <键入回车>

    > 2d  <键入回车>

    > 3d’ file

    更为复杂点的是,命令中含有用于过滤文本行的地址信息,同时要求执行多个命令,这时候要使用大括号{}。比如

    # sed ‘5,/^$/{   <键入回车>

    > /hello/d   <键入回车>

    >s/word/words/g   <键入回车>

    > }’ file

    其中,5,/^$/ 代表仅针对第5行到后边第一个空白行间的文本行,/hello/代表含有hello的文本行,s命令代表将word全部替换为words,g标记代表处理对应行中所有出现的word,没有g代表仅处理对应行中第一个word。

    注意:有些情况使用大括号可以不用键入回车,但是键入回车肯定可以保证不出问题,所以建议始终在使用大括号时键入回车!

    1.6.2 脚本文件方式

             了解了上边的命令行方式,就好了解脚本方式了。脚本方式就是将多条命令放置到一个文本文件中,其格式如下:

    /address/{

    Cmd1;

    Cmd2;

    Cmdn;

    }

             这种形式其实和sed命令行使用大括号是一样的,只是由于命令多了,写在文件了比较方便,而且便于重用。其中,内部的cmd可以是以上形式的嵌套,就是大括号里面还可以再有地址,然后在使用大括号,到括号里面又是命令。

    将以上内容存于文件中,然后使用以下命令,即可执行:

    sed –f script.file file

    PartII 初级Sed命令

    2.1 基本Sed命令语法

    Sed命令语法:[address]command

    Sed语法:sed [options] [actions]file

    1.      Sed –f sed.script file

    2.      Sed ‘actions’ file

    3.      Sed在命令行使用多条命令的三种方式:

    使用多个-e选项,每个后边接一条命令;

    使用分号分隔多条命令;

    在写闭合的单引号之前使用回车,每条命令后边加回车

    Sed使用#作为注释符号,#号后边紧跟n,相当于使用-n参数,不默认输出文本内容

    2.2 Sed主要选项

    -n      抑制命令自动输出patternspace中的内容,默认情况下,pattern space中的内容,如果执行完所有处理命令,结果会被输出,使用该选项使得patternspace中的内容不会自动输出,通常该选项和p命令一起使用,以便输出当前处理行,单独使用p命令,同一行会被输出两次。

    -f       用于使用sed脚本的情况,后接脚本文件名

    -e      后接单引号括起来的命令串,使用多个命令,可以通过多次使用-e选项实现

    -i       直接修改原文件内容,默认不输出到屏幕

    -r      在命令中使用扩展的正则表达式,扩展正则表达式,我们会在<<掌握awk命令>>中提到,强大的选项!!!(该选项不在本文讨论范文内)

    2.3 12种基本命令

    Subsititution:即s命令,文本替换命令(常用

    语法:[address]s/pattern/replacement/flag

    Address代表要处理的行,可以是行号,正则表达式,特定行中的部分文本片段

    Pattern代表模式字符串

    Replacement代表用来替换模式字符串的字符串

    Flag有n,g,p,w file四种,n代表(1-512)中一个数字,表示替换操作作用于当前行中出现的第几个pattern串;g代表替换操作处理当前行中出现的所有pattern串,p代表打印当前行,该标志通常与-n选项连用,表示只打印处理过的行;w file表示将处理行写入文件file中。

    注意:分隔用的/可以使用其他合法符号,比如!,:等,最后,不使用任何标志表示仅作用于第一个匹配

    Replacement中可用的三种特殊符号:& 代表pattern匹配的字符串, 代表由第几个(pattern)匹配的串,代表转义字符,在Replacement中只有这三个特殊符号,其他都不是特殊符号,不需要转义

    Delete,即命令d,删除命令,语法:[address]d(常用

    删除匹配形式的行,注意是删除整行,而不是仅删除行中匹配的模式字符串

    Append,Insert,Change,即命令a,i,c,追加、插入、更改命令,语法[address](a|i|c) eplacement

    Append在指定行后插入,insert在指定行前插入,change用replacement替换指定行

    List命令,即l命令,列出指定行中的不可打印字符,如tab键,换行符等

    Transform命令,即命令y,转换命令,最特殊的一个命令,所有其他命令都是对应单词的首字母,只有这个命令不是对应单词首字母,因为test(t)命令已经存在了。

    语法:y/abc/ABC/ 该命令用于对应字符转换,类似于tr,但没有tr命令应用范围广,abc与ABC必须字符个数相等,对应转换,而不能使用[0-9]这种形式,即a转换为A,b转换为B,c转换为C。

    Print命令,即p命令,打印匹配行,通常与选项-n一起使用,不使用-n同一行会被打印两次。特殊符号=,与p命令联合使用,可以输出行号,行号独立成行,=等号必须是地址后边第一个出现,在p命令之前(常用

    例子:输出第一行到第一个空行中的所有行,并输出行号

    1,/^$/{

    =

    p

    }

    Next命令,即n命令。输出当前行,并将下一行输入到模式空间中。(常用

    注意:出现在n命令之前的命令不会作用于新输入的行,出现在n命令之后的命令也不会作用于n命令输出去的行

    ReadWrite命令,即r和w命令,如法[address](r|w)file

    r,将文件读入到当前行之后

    w,将当前行写入到文件

    Quit命令,即q命令,遇到地址行就退出sed,其中匹配的地址行也要输出

    其中,s,d,p,n是最常用的几个命令,y是最特殊的一个命令,因为其它所有命令都是以单词首字母命名,它不是。


    PartIII    高级Sed命令

    3.1多行模式空间与备份空间

    多行模式空间(MultilinePattern Space):就是在模式空间中放置输入文件的多个行内容。

    备份空间(The Hold Space):用于备份Pattern Space中的内容的空间。

    3.210种高级Sed命令

    三组高级sed命令:

    1操作多行模式空间的命令(N,D,P)

    2处理模式空间与备份空间内容交换的命令(H,h,G,g,x)

    3 sed脚本控制流命令(b,t)

    N,D,P命令分别为n,d,p命令的大写形式,其含义类似,略有不同:

    N命令,与n不同,它不输出模式空间中的当前行,而是将下一行也输入到模式空间中,当前行与下一行之间插入一个’ ’,以下为示意图:

                                                                        图1. 调用N命令后的Multiline Space

    注意:调用N后只有最初和最后有^$标记, 前后并没有这些标记

    D命令不同于d命令,d命令删除Pattern Space中的内容,而D命令仅删除Multiline Space中第一个’ ’之前的内容,如图1 中,即删除“The Unix Operating System”,而“Is A interesting System”仍然存在。同时,它使得脚本的控制流转到脚本文件的第一行,跳过该命令的后续命令。

    P命令不同于p命令,p命令打印Pattern Space中的内容,而P命令仅打印Multiline Space中第一个’ ’之前的内容,如图1中,即仅打印“The Unix Operating System”.

    Hh命令,hold之意,将Pattern Space中的内容备份到Hold Space中,大写命令是追加到Hold Space中,小写命令是覆盖HoldSpace中的内容;

    Gg命令,get之意,即将Hold Space中的内容取到Pattern Space中,大写代表追加,小写代表覆盖。

    x命令,交换Pattern Space和Hold Space中的内容。

    b命令(branch)和t命令(test)用于控制sed脚本流程。

    b命令语法:[address]b[label]

    例子:

    :Hello

             Command

             Command

             /address/b Hello

             Command

    b命令使得脚本控制流转到:Hello的下一行,如果没有使用标签,则直接跳转到脚本结尾。

    t命令语法:[address]t [label]

    例子:

    s/ //

    t

    command

    t命令含义是,如果上边的替换命令s成功,则跳转到标签处,如果没有标签,跳转到脚本结尾,如果不成功则继续执行后续命令。

    总结,掌握Sed,掌握Shell的基本正则表达式,12中基本Sed命令+10中高级Sed命令,Sed命令除y命令(transform)外,其它命令都是英文单词首字母,很好记忆。当然,这里不是Sed的全部命令,其它一些命令不太常用,就不再介绍。最后一部分,我们以一些常见的sed命令处理案例,来加深理解上边的理论介绍部分,以便彻底掌握这个实用工具。

    PartIV 实践练习

    [d删除命令]

    $ sed 2d file          #删除file中的第2行

    $ sed 2,$d file            #删除第2行到最后一行的所有行

    $ sed /hello/ file      #删除包含hello的行

    $ sed 1d;5d;10d file    #删除第1,5,10行

    $ sed /^$/d file        #删除file中的空行

    $ sed 5,10!d file       #删除5-10以外的所有行

    总结:d命令有三种地址模式,行号,行中字符串片段,正则表达式,对于后两种需要使用//包围地址,如/hello/和/^$/,还有一点,两个地址间的逗号,表示作用范围为两个地址之间,!代表取补集

     

    [s 替换命令]

    $ sed s/test/Test/ file              #用Test替换每行中第一个test

    $ sed s/test/Test/5 file              #用Test替换每行中第5个出现的test

    $ sed s/test/Test/g file              #用Test替换每行中所有test

    $ sed ns/^test/Test/p file          #-n与p合用,仅显示发生替换操作的行,

    #Test替换以test开头的行的开头的test

    $ sed s/^192.168.0.1/&localhost file  # &表示匹配到的内容,用

    #192.168.0.1localhost替换以192.168.0.1

    #开头的行的开头的192.168.0.1

    $ sed ns/(love)able/1rs/p file   #1代表(love)匹配到的内容,用lovers

    #替换包含love的行中第一个出现的love

    $ sed s#10#100#g file                 #用100代替每行出现的10,这里#等于/

    $ sed n/test/,/check/p file         #仅打印第一包含test的行到第一个包含

    #check的行之间的所有行

    $ sed n5,/^test/p file              #打印第5行到第一个以test开头的行

    #之间的所有行

    $ sed /test/,/check/s/$/HelloEnd      #在第一个包含到第一个包含check的行

    #后边追加HelloEnd

    $ sed e1,5des/test/check/ file  #删除1-5行的内容,将文件中每行第一个

    #test替换为check,前边命令影响后边命令

    总结:命令中体现了p命令的使用,通常与-n选项连用,s命令是最常用的,注意分隔符可以用其他符号代替,注意逗号可以表示地址区间,以及//包围地址的使用

     

    [n下一行命令]

    $ sed /test/{n;s/aa/bb/} file       #读到含test的行,输出该行,然后

    #读入下一行,用bb替换下一行出现

    #的第一个aa,循环执行以上动作

    该命令可以写为以下方式

    $ sed /test/{  <键入换行符>

    >n  <键入换行符>

    >s/aa/bb <键入换行符>

    >} file

    总结:n命令前边的命令不会作用于下一行,n命令后边的命令不会作用于当前行

    [r 文件读入命令]

    $ sed /test/rfile2 file1    #将file2的内容插入到file1中含有test的每一行之后

    [w 文件写入命令]

    $ sed /test/wfile2 file1   #将file1中每个含有文本test的行追加到file2中

    [a 追加命令]

    $ sed /test/a hisis append line file #在含有文本test的行后边插入一行内容为

                                            #thisis append line的文本

    [i 插入命令]

    $ sed /test/i hisis a insert line file #类似如a命令,在对应行前边插入

    [c 替换命令]

    $ sed 3,5c hisis a change linefile    #将文件file的第3-5行内容替换为一行,

                                              #其内容为this is a change line

    [y 转换命令]

    $ sed 1,10y/abcd/ABCD/ file      #将file前10行中所有的字符a,b,c,d转换为大写

    [q 退出命令]

    $ sed 10q file                   #处理完(默认为打印)第10行,sed命令结束

                                      #q命令与b,t等命令可以用于流程控制

    [N 下一行追加命令]

    问题描述:用sed实现去换行的功能,即tr d 的功能

    sed fscript.file file   #其中script.file为sed脚本文件,名字可以随便取

                              #file为待处理文件

    Script.file脚本文件内容如下:

     

    {

    N             #将下一行追加到模式空间,现在空间中有两行内容,中间用 分隔

    s/ //        #删除 ,执行完这里sed对下一行继续处理

    }

    当然,左大括号{左边可以通过加地址信息限制处理哪几行,这个功能当然可以不写脚本文件,直接在命令行执行,如下:

    sed N;s/ // file

    再强调一次,脚本文件都可以写成命令行方式,放过来也成立,就是看你觉得怎么方便而已!

     

    [N P D 循环] #联合使用N-P-D,操作控制流

    问题描述:如下文本文件,如果UNIX System出现以下情况:UNIX是一行的最后一个单词,System是下一行的第一个单词,则将UNIX System替换为UNIX Operating System,新的换行符在System之后。

    file内容如下:

    Here are examples of the UNIX

    System. Where UNIX

    System appears, it should be the UNIX

    Operating System.

    处理后输出结果为:

    Here are examples of the UNIX Operating System.

    Where UNIX Operating System appears, it should be theUNIX

    Operating System.

     

    实现脚本如下:

    /UNIX$/{

        N   #在UNIX结尾的行后追加下一行,中间有 分隔

        s/ (System.*)/ Operating 1 /  #替换,这里的特殊用法稍后讲述

        P   #输出 之前的内容

    D   #删除 之前的内容,并跳转至脚本第一行,即/UNIX$/{处

    }

     

    备注:N是在模式空间追加一行,两行之间有一个分隔符 ;P是打印多行模式空间中第一个 之前的内容,也就是第一行;D是删除第一个 之前的内容,并使得控制流程跳转至脚本第一行,如果D后边还有命令,执行D后,后边的命令式执行不到的。

     

    如果将脚本中替换命令那行换为以下一句,输出结果略有不同:

    s/ System/ Operating System /

    输出结果为:

    Here are examples of the UNIX Operating System

    .Where UNIX Operating System

     appears, itshould be the UNIX

    Operating System.

     

    这里面有一些标点的问题,因此,我们做了特别处理,说明如下:

    (System. *)代表System后边有一个任意字符,这是为了处理空格和句号的,后边*前边有个空格,这里看不出来,实际是输入了一个空格,这个代表,之后出现0个或多个空格,而其中用反斜杠和小括号括起来,代表后边1指的就是这个匹配。如果这里有不明白的,可以翻看前边关于()和1的介绍。

    [h,H,g,G,x模式空间与备份空间命令]

    这几个命令就是在两个空间中互相操作,比较好理解,这里不再举例。

    [b,t]流程跳转命令,根据前边的理论介绍也比较好理解,不再举例。


  • 相关阅读:
    Notice: Only variable references should be returned by reference(PHP版本兼容性问题)
    App 开发:Hybrid 架构下的 HTML5 应用加速方案
    Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?
    前端切图+网页排版的注意事项和经验分享
    php提示 Notice: Use of undefined constant name
    如何预测一个互联网产品的未来—一套关于产品的数学模型
    以 MAMP 为 Mac OS X 安装并设置 PHP开发环境
    关于EINTR错误的理解【转】
    socket中的函数遇见EINTR的处理【转】
    Ubuntu10.04中利用V4L2读取摄像头数据并保存成文件【转】
  • 原文地址:https://www.cnblogs.com/pangblog/p/3400258.html
Copyright © 2020-2023  润新知