windowssedgnu-sed

Insert Line with SED Before Each Multiline Range


How can I insert a line before each multiline range block and indent the blocks in gnu sed on windows? The files contain many code blocks of various length starting and ending with ```. Answers to many similar questions using a single line pattern don't use ranges. There are two similar questions: Insert line below text range with sed and sed: Appending after a block.

This code indents all code blocks as required:

sed '/```/,/```$/ s/\(.*\)/ \1/' test.md

I don't understand how to insert the === line before each code block but I understand grouping with {} is required to process the block after inserting the line. The questions above seem more complex requiring a buffer but this file should be able to be processed sequentially without a buffer.

I expect something like this attempt should work with the newline detail before the group:

sed '/```/,/```$/ {s/\(.*\)/ \1/}' test.md

test.md

a
b
```
c
d
e
```
f
g

Required

a
b
===
    ```
    c
    d
    e
    ```
f
g

Solution

  • With GNU sed:

    $ cat file
    1
    ```
    2
    ```
    3
    ```
    4
    ```
    5
    $ sed '/^```$/{ s/^/===\n    /; :a; n; s/^/    /; /^    ```$/b; ba; }' file
    1
    ===
        ```
        2
        ```
    3
    ===
        ```
        4
        ```
    5
    

    (The cool sedsed can show how it works in details.)


    With awk:

    $ awk '/^```/ { if (!f) { print "===" } f++ } f { print "    " $0 } f==2 { f=0; next } !f' file
    1
    ===
        ```
        2
        ```
    3
    ===
        ```
        4
        ```
    5