【问题标题】:sed match multiple lines containing special characters and replace part of the matched patternsed 匹配包含特殊字符的多行并替换匹配模式的一部分
【发布时间】:2018-08-28 20:16:16
【问题描述】:

将以下几行视为文本文件:

START This is a 
sample paragraph that has special characters like new lines

spaces, tabs, quotes "abc", equals =, angular brackets <abc>, front slash / and might contain the starting string that should be ignored
START and 

END

START

dfgfah

END

使用 sed,我想只替换第一次出现的 START 和第一次出现的 END 之间的文本。

我期待的结果是这样的:

START new_text END

START

dfgfah

END

我尝试的是这样的:

sed ':a;N;$!ba;s/START.*END/START New text END/' sample.txt>sample_2.txt

但结果是:

START New text End

在第一次出现 END 之前如何替换?

【问题讨论】:

  • 这对于 Perl 来说是微不足道的:perl -0777 -pe 's/START.*?END/START New text END/s'
  • 所有版本的 linux 都支持 perl 吗?它必须在 SuSe、IBM NIX 和其他几个版本上得到支持
  • Perl 几乎可以在所有操作系统上运行(包括 Linux 和更深奥的东西,如 HP/UX、VMS 等)。不过,我不知道它是否是标准操作系统安装的一部分。

标签: bash shell sed


【解决方案1】:

使用 GNU sed:

sed '0,/START/{:a;/END/!{N;ba};s/.*/START new_text END/;}' file
  • 0,/START/:从START 的第一次出现开始
  • :a;/END/!{N;ba}:将新行添加到模式空间,直到找到 END
  • 当上述循环结束时,将合并的行替换为START new_text END

【讨论】:

    【解决方案2】:

    您可以使用: 定义标签和b 分支到sed 脚本中的标签。

    -n 选项告诉sed 不自动打印任何行。相反,您可以使用p 命令打印这些行。

    在以下示例中,:head 循环循环遍历部分直到第一个 START:tail 循环循环遍历第一个 END 之后的文本。 :start 循环遍历第一个 STARTEND 之间的部分。

    :head:tail 循环在每行 (n) 打印 (p) 并在到达文件末尾 ($q) 时退出。 :start 循环不打印,只是忽略内容。当找到 END 时,新文本将被插入 (s) 并打印 (p)。

    cat <<EOF |
    START This is a 
    sample paragraph that has special characters like new lines
    
    spaces, tabs, quotes "abc", equals =, angular brackets <abc>, front slash / and might contain the starting string that should be ignored
    START and 
    
    END
    
    START
    
    dfgfah
    
    END
    EOF
    sed -n '
    :head
    /^START/{
      :start
      n
      $q
      /^END/{
        s/^/START New text /
        p
        n
        :tail
        p
        $q
        n
        b tail
      }
      b start
    }
    p
    $q
    n
    b head
    '
    

    上述技术取自The Geek Stuff's sed tutorial的第一个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多