【问题标题】:How to sed a block of text with specific pattern?如何 sed 具有特定模式的文本块?
【发布时间】:2014-12-10 18:50:39
【问题描述】:

我的文件看起来像这样

...
%pythons
Albino
Black Bee
Bumble Bee
%end

%boa
Albino
Jungle
Pastel
%end
...

我想从这个文件匹配模式中提取一个完整的块用于保存或替换目的。块中的行数可能非常多。我需要通用解决方案。 我正在寻找这样的东西

sed -n '/^%boa(**something here**)^%end$//p' snakes > boa
sed 's/^%boa(**something here**)^%end$/(**new block**)/' snakes > snakes_updated

我正在寻找专门的 sed 解决方案。任何带有解释的建议将不胜感激。

【问题讨论】:

  • 您要删除一个块还是只想要该块?
  • 我需要将此块保存到另一个文件或如果需要用另一个块替换它

标签: regex bash sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -i -e '/%boa/,/%end/{w fileb' -e '/%end/!d;r filec' -e 'd}' filea

这会将%boa%end 之间的部分写入fileb 并将其替换为filec 的内容。 filea 的内容被使用-i 标志编辑的操作替换。

【讨论】:

    【解决方案2】:

    如果我理解的很好,你可以这样做grouping commands这样:

    sed -i.bak '/^%boa/,/%end/ {
        wboas
        d
    }' file
    

    使用w command,您可以将addresses /^%boa/,/%end/ 之间的内容写入文件boas
    使用d command,您将删除原始文件中的这些行(在-i option 的帮助下)。

    原始文件:

    $ cat file
    ...
    %pythons
    Albino
    Black Bee
    Bumble Bee
    %end
    
    %boa
    Albino
    Jungle
    Pastel
    %end
    ...
    

    示例

    $ sed -i.bak '/^%boa/,/%end/ {
    >     wboas
    >     d
    > }' file
    
    $ cat boas
    %boa
    Albino
    Jungle
    Pastel
    %end
    
    $ cat file
    ...
    %pythons
    Albino
    Black Bee
    Bumble Bee
    %end
    
    ...
    

    此外,如果您需要用其他内容替换该块(比如"hello\n world"),您可以在其后附加a command

    sed -i.bak '/^%boa/,/%end/ {
        wboas
        /^%boa/a \
        hello \
        world
        d
    }' file
    

    示例

    $ sed -i.bak '/^%boa/,/%end/ {
    >     wboas
    >     /^%boa/a \
    >     hello \
    >     world
    >     d
    > }' file
    
    $ cat file
    ...
    %pythons
    Albino
    Black Bee
    Bumble Bee
    %end
    
        hello 
        world
    ...
    
    $ cat boas
    %boa
    Albino
    Jungle
    Pastel
    %end
    

    【讨论】:

      【解决方案3】:

      好像你想要这样的东西,

      $ sed -n '/^%boa$/,/^%end$/p' file
      %boa
      Albino
      Jungle
      Pastel
      %end
      

      打印特定范围内的行。

      【讨论】:

      • 谢谢!有没有办法用这种模式将这样的块替换为另一个文本块?使用 sed 's/pattern/block/' 文件?
      • 将块保存到另一个文件sed -n '/^%boa$/,/^%end$/p' infile > outfile 但我不知道如何进行块替换。
      • 感谢您的回答。
      【解决方案4】:

      使用perl -0,您可以轻松地搜索和替换该文件中的一个块:

      perl -0pe 's~(?ms)\R%boa.*%end(\R|\z)~\n---\nfoo\nbar\nbaz\n---\n~' file
      ...
      %pythons
      Albino
      Black Bee
      Bumble Bee
      %end
      
      ---
      foo
      bar
      baz
      ---
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        • 1970-01-01
        • 2013-10-15
        • 2021-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多