How do I compile a block of text with a specific pattern?

I have a file similar to this

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

%boa
Albino
Jungle
Pastel
%end
...

      

I would like to edit one whole block from this file to match the template for save or save purposes. The number of lines in a block can be very large. I need a general solution. I am looking for something like this

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

      

I'm looking specifically for a sed solution. Any suggestions with an explanation would be much appreciated.

+1


source to share


4 answers


This might work for you (GNU sed):

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

      



This writes the section between %boa

and %end

in fileb and replaces it with the contents of filec. The contents of filea are replaced with the edited operations using the flag -i

.

+1


source


If I understand well, you can do this command grouping this way:

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

      

With the command, you write content between addresses to the boas . With the command, you remove those lines in the original file (with ). w

/^%boa/,/%end/


d

-i

Original file:

$ cat file
...
%pythons
Albino
Black Bee
Bumble Bee
%end

%boa
Albino
Jungle
Pastel
%end
...

      

Example



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

$ cat boas
%boa
Albino
Jungle
Pastel
%end

$ cat file
...
%pythons
Albino
Black Bee
Bumble Bee
%end

...

      


Also, if you need to substitute a block with something else (say "hello\n world"

), you can add it with a

command
:

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

      

Example



$ 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

      

+1


source


It sounds like you want something like this,

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

      

It prints lines that fall within a specific range.

0


source


Using perl -0

, you can easily find and replace one block from this file:

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
---
...

      

0


source







All Articles