Loading

sed命令

参考:

https://blog.csdn.net/BearStarX/article/details/104612035?utm_medium=distribute.pc_relevant.none-task-blog-2~default~OPENSEARCH~default-4.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~OPENSEARCH~default-4.no_search_link

工作机制

每次读取一行文本至模式空间,在模式空间中完成处理;将处理结果输出至标准输出设备;

语法

sed [option] {script} [input-file]

option参数

  • -r 支持扩展正则表达式。
  • -n 静默模式
  • -e script -e script指定多脚本运行
  • -f /path/to/script
  • -i 直接修改源文件

地址定界

  • #

    指定行

  • $

    最后一行

  • /regexp/

    任意能够被/regexp/匹配的行。

    sed '/^#/d' filename 删除以# 开头的行。

  • \%regexp%

    同上,只不过换作%regexp边界符

  • /regexp/I 匹配是忽略大小写

  • \%regexp%I 同上

  • startline, endline

    1. #,/regexp/ 从#开始,到第一次被/regexp所匹配到的行结束。中间所有的行;

    2. #,#

    3. /regexp1/, /regexp2/

      从第一次被/regexp1/匹配到的行开始,到第一次被/regexp2/匹配到的行结束,中间的所有行

    4. #,+n:从#行开始,一直到向下的n行

  • first~step:指定起始行,以及步长

编辑命令

  • d 删除模式空间中的行。 sed '1,2d' filename

  • = 显示行号

    sed '/^#/=' filename

  • a \text附加text

    1. sed '/^#/a \new line' filename
    2. sed '1a \new line \n second line'
  • i \text 插入text,支持\n实现多行插入

  • c \text 用text替换匹配到的行

    1. sed '5,7c \new text' filename
    2. sed '^#/c \new text'
  • p 打印模式空间中的行 sed ‘5,7p’ /etc/fstab---5-7行的内容显示两遍,使用-n才符合我们的期望

  • s/regexp/replacement/

    替换由regexp所匹配到的内容为 replacement

    1. g: 全局替换
    2. i: 不区分大小写

    sed 's/^#//g' filename

  • w /path/to/somefile

    把指定的内容另存到/path/to/somefile路径指定的文件中。

    sed 5,9w /tmp/test1.txt filename

  • r /path/to/somefile

    在文件的指定位置插入另一个文件的所有内容,完成文件合并

    sed ‘8r /etc/issue’ /etc/fstab ---将issue的第8行之后的内容读进来放到fstab之前

sed 高级命令

  • h 用模式空间中的内容覆盖保持空间的内容
  • H 把模式空间中的内容追加至保持空间中内容的后面
  • g从保持空间中取到其内容,并将其覆盖到模式空间中的内容
  • G从保持空间中获取内容,并将其追加到模式空间中的内容的后面
  • x把保持空间和模式空间中的内容进行交换
  • n 读取匹配的行的下一行到模式空间。覆盖模式空间原有的内容
  • N 读取匹配到的行的下一行至模式空间,追加在模式空间中原有内容的后面
  • d 删除模式空间中的内容
  • D 删除多行模式空间的首行

例子:

  1. sed 'G' filename 在文件中的每行后面添加空白行

  2. sed '$!d' filename 保留最后一行

  3. sed '/^$/d;G' filename 证指定的文件每一行后方有且只有一个空白行;

  4. sed 'n;d' filename 保留奇数行

  5. sed -n '1!G;h;$p' filename 全文倒叙显示

  6. sed '$!N;$!D' filename 显示最后两行

    例子: echo -e 'a\nb\nc\nd' | sed '$!N;$!D'

    处理流程

    说明:

    CURRENT => 当行行

    PATT => 模式空间

    COMM => 命令

    步骤:

    # 读取第一行
    CURRENT => a
    
    # 将 当前行内容读取到模式空间
    PATT => ^a$
    # 执行 $!N 命令, 可以将$! 理解为是否为最后一行。注意, !是跟$结合。$代表最后一行,$!代表非最后一行。
    # 所以执行完 N之后。
    PATT => ^a\nb$
    
    # 执行$!D,同样,如果不是最后一样则删除首行
    PATT => ^b$
    
    # 接下来继续执行 $!N
    PATT => ^b\nc$
    # 执行 $!D
    PATT => ^c$
    
    # 执行 $!N
    PATT => ^c\nd$
    
    # 因为d 不满足 $!的条件,所有D命令不执行。
    
  7. 常见用途

    • 查找关键词作全局替换

      sed -i 's/a/b/g' filename

    • 查找/etc/crontab第17行,并把0,30 替换为15,45

      sed -i '17s/0,30/15,45' crontab

    • 查找/etc/crontab中的关键字script.sh, 并把15,14 替换为0,30

      sed -i '/script.sh/s/15,45/0,30/' /etc/crontab

    • 在第17行后添加新的 一行内容

      sed -i '17a\0 * * * * root /root/test.sh' /etc/crontab

    • /etc/crontab中查找关键字script,并且该关键字的下一行追加一行新内容

      sed -i '/^.*script.*$/a\30,45 * * * * root /root/check.sh' /etc/crontab

    • /etc/crontab中查找关键字check.sh,并且删除该行

      sed -i '/check.sh/d' /etc/crontab

    • 显示第17到18行之间的内容

      sed -n '17,18p' /etc/crontab

    • 在最后一行追加一行0 * * * * root /root/check.sh

      sed -i '$a\0 * * * * root /root/check.sh' /etc/crontab

    • sed 命令处理换行符,例如替换或者删除

      sed ':label;N;s/\n/:/;b label' filename

      sed ':label;N;s/\n/:/;t label' filename

      上面的两条命令可以实现将文件中的所有换行符替换为指定的字串,如命令中的冒号。命令的解释:
      :label; 这是一个标签,用来实现跳转处理,名字可以随便取(label),后面的b label就是跳转指令
      N; Nsed的一个处理命令,追加文本流中的下一行到模式空间进行合并处理,因此是换行符可见
      s/\n/:/; ssed的替换命令,将换行符替换为冒号
      b label 或者t label b / tsed的跳转命令,跳转到指定的标签处
      标签跳转和N的追加命令实现了每一行的不间断放入模式处理空间,从而不会漏掉每一个换行符,而没有标签的话跳转的话,就只能每两行替换掉一个换行符,对比效果:

      $  echo "a,b,c,d" |sed 's/,/\n/g'|sed ':x;N;s/\n/,/;b x'
      a,b,c,d
      $  echo "a,b,c,d" |sed 's/,/\n/g'|sed 'N;s/\n/,/'
      a,b
      c,d
      
      
posted @ 2021-10-13 13:52  Test002  阅读(14)  评论(0)    收藏  举报