How to substitute a paragraph in file?

瘦欲@ 提交于 2019-12-02 10:20:09
Jonathan Leffler

The sed syntax you show is not entirely accurate; if it worked, then you must have used:

sed -n '/aStyle.Landscape {/,/}/p'

to print the lines from 'aStyle.Landscape' to the closing brace.

If you want to replace that paragraph, then you can do:

sed '/aStyle.Landscape {/,/}/c\
MImAbstractKeyAreaStyle.Landscape {\
    /*** Label Setttings ***/\
    label-margin-top: 6.0mm;\
    label-margin-left-with-secondary: +1;\
    secondary-label-separation: 2;\
    ...\
}'

Note that each line in the replacement text except the last is followed by a backslash.

You might find it better to use a script file:

sed -f sed.script css.file

When I ran the script above, copied verbatim from this answer into a file 'xx', on the CSS fragment from the question (in 'xx.css') using sh xx < xx.css, the output I got was:

    /*** Debugging ***/
    draw-button-bounding-rects: false;
    draw-button-rects: false;
    debug-touch-points: false;
    draw-reactive-areas: false;
}

MImAbstractKeyAreaStyle.Landscape {
    /*** Label Setttings ***/
    label-margin-top: 6.0mm;
    label-margin-left-with-secondary: +1;
    secondary-label-separation: 2;
    ...
}

MImAbstractKeyAreaStyle.Portrait {

You said you got everything on one line...I wonder how you ran the script? If everything was 'on one line', I wonder if you do something like:

output=$(sed ... file.css)

followed by:

echo $output

This would flatten everything to one line (think of it as minimization). The shape of the CSS would be preserved if you wrote instead:

echo "$output"

This question shows how the 'flattening' problem arose. There were two levels of shell interpretation (the shell that runs the su command, and the shell that is run by the su command), which is enough to give anyone a headache. Doubling up the backslashes might be sufficient, but I'd create a script and run that.

This might work for you to:

cat <<\EOF > new_para.txt
MImAbstractKeyAreaStyle.Landscape
    /*** Label Setttings ***
    label-margin-top: 6.0mm;
    label-margin-left-with-secondary: +1;
    secondary-label-separation: 2;
    ...
}
EOF
> MImAbstractKeyAreaStyle.Landscape
>     /*** Label Setttings ***
>     label-margin-top: 6.0mm;
>     label-margin-left-with-secondary: +1;
>     secondary-label-separation: 2;
>     ...
> }
sed -i -e '/aStyle.Landscape {/,/}/{/}/r new_para.txt' -e ';d}' file.css

If the replacement paragraph is of the same length and your using GNU sed, this would work to:

sed -i -e '/aStyle.Landscape {/,/}/{R new_para.txt' -e ';d}' file.css

N.B. The last method only works for a single replacement, unless each paragraph to be replaced (in order) is in the new_para.txt file. This does give the user a chance to tailor each replacement paragraph, a subtle but powerful difference.

EDIT:

To achieve the same result without an intermediate file:

cat <<\EOF | sed -i -e '/aStyle.Landscape {/,/}/{/}/r /dev/stdin ' -e ';d}' file.css
MImAbstractKeyAreaStyle.Landscape
    /*** Label Setttings ***
    label-margin-top: 6.0mm;
    label-margin-left-with-secondary: +1;
    secondary-label-separation: 2;
    ...
}
EOF
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!