• Sed基本入门[1] 基础知识


    1、What's sed?


    如果你是一个开发、系统管理员或者数据库管理员又或者是it管理员,或者只是一个经常在unix/linux环境下工作的人,你应该掌握sed和awk。
    Sed→Stream Editor,它是一个非常强大的工具,可以用来操作、过滤和转换文本。Sed可以从文件中获取输入,也可以从管道中获取输入。

    2、Basic Syntax


    sed [options] {sed-commonds} {input-file}

     sed一次从input-file中读取一行文本,然后在这一行文本上执行sed-commonds,接着读取下一行文本,再执行sed-commonds,重复执行这个过程,直到读取input-file的最后一行之后。

    sed-commonds可以是一个命令也可以是一组命令。如果是一个命令,可以如以下的方式执行:

    sed -n 'p' /etc/passwd

    在上面的示例中,-n为选项 p为命令,/etc/passwd为输入文件。

    如果需要执行的是一组命令,需要在每个命令前加上选项-e,表示是需要执行的命令,其基本语法为:

    sed [options] -e {sed-command-1} -e {sed-command-2} {input-file} 

    示例:

    $ sed -n -e '/^root/ p' -e '/^nobody/ p' /etc/passwd 

    如果通过几个-e参数执行多个命令,可以把他们通过反斜杠分成多行,例如:

    $ sed -n \
    -e '/^root/ p' \
    -e '/^nobody/ p' \
    /etc/passwd 

    你也可以把通过花括号把要执行的多个sed命令写到一组,其基本语法为:

    sed [options] '{
    sed-command-1
    sed-command-2
    }' input-file

    示例:

    $ sed -n '{
    /^root/ p
    /^nobody/ p
    }' /etc/passwd

    我们还可以把要执行的sed命令写到一个文件中,然后通过-f选项来使用该文件,其基本语法为:

    sed [options] -f {sed-commands-in-a-file} {input-file}

    示例:

    $ vi test-script.sed
    /^root/ p
    /^nobody/ p
    $ sed -n -f test-script.sed /etc/passwd 

    3、Sed Scripting Flow


    PEPR:

    • Read:把一行文本读取到模式空间(Pattern Space,一个内部的临时buffer)。
    • Execute:在模式空间内保存的文本上执行sed命令。如果有多个sed命令,则会依次执行。
    • Print:打印输出模式空间中的文本,打印后,模式空间为空。
    • Repeat:重复执行上述操作,直到文件的末尾。

    具体流程可以参考下图:

     4、p command and Address Range


    在接下来的示例中,我们会多次以文本文件employee.txt作为sed操作的对象进行示范:

    $ vi employee.txt 
    101,John Doe,CEO 
    102,Jason Smith,IT Manager
    103,Raj Reddy,Sysadmin
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager

    使用p命令,可以打印当前模式空间中的内容。

    为什么需要p命令?
    3 Sed Scripting Flow 中提到了Print,也就是说sed自动也会打印模式空间中的内容,那为什么还需要有一个专门的打印命令p呢?因为使用p命令,你可以更加详细的指定打印哪些内容或者说不打印哪些内容。通常情况下,使用p命令时,配合使用-n选项来抑制标准sed流程中的默认打印,否则文本可能会打印两行:

    $ sed 'p' employee.txt 
    101,John Doe,CEO
    101,John Doe,CEO
    102,Jason Smith,IT Manager
    102,Jason Smith,IT Manager
    103,Raj Reddy,Sysadmin
    103,Raj Reddy,Sysadmin
    104,Anand Ram,Developer
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager
    105,Jane Miller,Sales Manager

    使用-n选项后:

    $ sed -n 'p' employee.txt 
    101,John Doe,CEO
    102,Jason Smith,IT Manager
    103,Raj Reddy,Sysadmin
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager 

    Address Range:

    通过在sed命令前指定地址范围,可以只在特定的行上执行sed命令,否则默认在所有的行上执行。例如以下代码片段只在第二行上执行打印命令:

    $ sed -n '2 p' employee.txt 
    102,Jason Smith,IT Manager 

    而以下代码片段只在2到最后一行行上执行打印命令:

    $ sed -n '2,$ p' employee.txt 
    102,Jason Smith,IT Manager 
    103,Raj Reddy,Sysadmin 
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager

    常见的地址范围用法:

    • n:匹配第n行
    • n,m:匹配第n到m行
    • n,+m:匹配从第n行及接下来的m行
    • n~m:匹配从第n行开始的每m行记录,例如:1~2匹配1,3,5,7,...;2~2匹配2,4,6,8,...;2~3匹配2,5,8,....

    模式匹配(Pattern Matching)

    正如可以使用地址范围一样,也可以使用一个模式匹配,例如以下几个示例:

    打印匹配模式"Jane"的行:

     sed -n '/Jane/ p' employee.txt 
    105,Jane Miller,Sales Manager 

    打印从匹配模式"Raj"开始的行到匹配模式"Jane"的行:

    $ sed -n '/Raj/,/Jane/ p' employee.txt 
    103,Raj Reddy,Sysadmin 
    104,Anand Ram,Developer 
    105,Jane Miller,Sales Manager

     甚至可以结合模式匹配和地址范围,例如打印从匹配模式"Jason"及后面的两行:

    $ sed -n '/Jason/,+2 p' employee.txt 
    102,Jason Smith,IT Manager 
    103,Raj Reddy,Sysadmin 
    104,Anand Ram,Developer

    ! 的用法:在地址范围或模式匹配后 加上 ! 可以表示原条件的相反条件,例如以下示例,如果没有加 ! 则表示打印1、3、5行,但是加上! 后,则表示打印其余的行

    $ sed -n '1~2 ! p' employee.txt 
    102,Jason Smith,IT Manager
    104,Anand Ram,Developer


    5、Some Other Common commands


    • d:Delete Lines

      the lower case d command deletes the current pattern space, reads the next line from the input-file to the pattern space, aborts the rest of the sed commands and starts the loop again.

    • w:Write Pattern Space to File

    sed不会修改原文件的内容,只是修改模式空间中的内容

    几个示例:

    删除所有行:

    sed 'd' employee.txt

    删除第2行:

    sed '2 d' employee.txt 
    101,John Doe,CEO 
    103,Raj Reddy,Sysadmin 
    104,Anand Ram,Developer 
    105,Jane Miller,Sales Manager

    删除1到4行:

    $ sed '1,4 d' employee.txt 
    105,Jane Miller,Sales Manager 

    删除奇数行:

    $ sed '1~2 d' employee.txt
    102,Jason Smith,IT Manager
    104,Anand Ram,Developer 

    删除第一次出现"Jason"的行到第4行:

    $ sed '/Jason/,4 d' employee.txt 
    101,John Doe,CEO 
    105,Jane Miller,Sales Manager

    删除空行:

    sed '/^$/ d' employee.txt

    删除注释行:

    sed '/^#/ d' employee.txt

    将employee.txt中的内容逐行写入文件output.txt中:

    $ sed 'w output.txt' employee.txt
    101,John Doe,CEO 
    102,Jason Smith,IT Manager 
    103,Raj Reddy,Sysadmin 
    104,Anand Ram,Developer 
    105,Jane Miller,Sales Manager

    把第2行到最后一行的数据写入文件output.txt:

    $ sed -n '2,$ w output.txt' employee.txt 

     6、直接修改原文件


    我们已经知道了默认sed是不会修改原文件的,为了将修改后的文本写回原文件,可以有以下几种方法:

    可以通过w命令将修改后的文本写入一个新文件,然后将新文件重命名为原文件的名字。(注意不能直接使用w命令将新内容写回原文件,否则原文件内容会被清空,达不到效果。)

    sed -e '2d' -e 'w output.txt' employee.txt 
    mv output.txt employee.txt 

    还可以通过标准输出重定向写入一个新文件,然后将新文件重命名为原文件的名字。(注意重定向的文件不能是原文件,否则原文件内容会被清空,达不到效果。)

    sed 's/John/Johnny/' employee.txt > new-employee.txt
    mv new-employee.txt employee.txt 

    以上两种方法都得通过一个中间的文件间接修改,其实可以通过一个选项 -i 来更直接的修改原文件。

    $ sed -i 's/John/Johnny/' employee.txt

    这样employee.txt的内容就直接被修改了,为了谨慎起见,我们可以通过以下方法在修改原文件前将原文件进行备份

    sed -i.bak 's/John/Johnny/' employee.txt 

    这样就会首先将原文件备份为employee.txt.bak

  • 相关阅读:
    NSArray和NSMutableArray
    NSString和NSMutableString
    关于self指针
    匆匆这一年
    8步共振项目管理体系(8):项目实施过程中的辅助规范
    8步共振项目管理体系(7):项目实施过程的基本规范
    8步共振项目管理体系(5):项目管理的组织及制度保证
    8步共振项目管理体系(2):实施项目成功的标准和必要条件
    8步共振项目管理体系(3):实施顾问和项目经理的素质要求
    8步共振项目管理体系(6):健康的企业文化、团队文化
  • 原文地址:https://www.cnblogs.com/yangfengtao/p/2982228.html
Copyright © 2020-2023  润新知