如何替换文件中的段落?

时间:2011-12-10 05:02:08

标签: bash sed substitution busybox

我想要更改多行文件。这是一个CSS文件,我想将一个部分换成另一个部分。

这是文件的摘录:

    /*** 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: 0.6mm;
    label-margin-left-with-secondary: -1; /* not used, labels are centered horizontally */
    secondary-label-separation: 0;

    /*** Behaviour ***/
    touchpoint-horizontal-gravity: 32px;
    touchpoint-vertical-gravity: 20px;

    /*** Key Geometry ***/
    key-height-small: -1; /* unused */
    key-height-medium: 46px;
    key-height-large: 66px;
    key-height-x-large: 82px;
    key-height-xx-large: -1; /* unused */

    key-width-small-fixed: -1; /* unused */
    key-width-medium-fixed: 76px;
    key-width-large-fixed: 93px;
    key-width-x-large-fixed: 178px;
    key-width-xx-large-fixed: 244px;
    key-width-stretched-fixed: -1; /* unused */

    key-margin-left: 4px;
    key-margin-top: 0px;
    key-margin-right: 4px;
    key-margin-bottom: 12px;

    padding-left: 11px;
    padding-top: 8px;
    padding-right: 11px;
    padding-bottom: 8px;

    /*** Key Area Geometry ***/
    size: 854 -1;
}

MImAbstractKeyAreaStyle.Portrait {

如果我使用sed -n '/aStyle.Landscape {/,/}/p'它会打印正确的段落,但我想用另一段替换它。我尝试了sed '/aStyle.Landscape {/}/s/aStyle.Landscape {/something/'和类似但我遗漏了一些东西。

2 个答案:

答案 0 :(得分:1)

您显示的sed语法并不完全准确;如果它有效,那么你必须使用:

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

将'aStyle.Landscape'中的线条打印到右大括号。

如果要替换该段落,则可以执行以下操作:

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

请注意,除了last之外的替换文本中的每一行后面都有一个反斜杠。

您可能会发现使用脚本文件更好:

sed -f sed.script css.file

当我运行上面的脚本时,使用sh xx < xx.css从问题(在“xx.css”中)的CSS片段中将此答案逐字复制到文件“xx”中,我得到的输出是:

    /*** 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 {

你说你把所有东西放在一条线上......我想知道你是怎么运行这个剧本的?如果一切都“在一条线上”,我想知道你是否做了类似的事情:

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

接下来是:

echo $output

这会使所有内容变为一行(将其视为最小化)。如果您改为编写CSS,将保留CSS的形状:

echo "$output"

question显示了“扁平化”问题是如何产生的。有两个级别的shell解释(运行su命令的shell,以及由su命令运行的shell),这足以让任何人头疼。加倍反斜杠可能就足够了,但我会创建一个脚本并运行它。

答案 1 :(得分:1)

这可能对您有用:

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

如果替换段落长度相同且使用GNU sed,则可以:

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

N.B。除非每个要替换的段落(按顺序)在new_para.txt文件中,否则最后一个方法仅适用于单个替换。这确实为用户提供了定制每个替换段落的机会,这是一个微妙而有力的差异。

编辑:

在没有中间文件的情况下实现相同的结果:

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