如何在第一次出现后使用sed命令替换一行?

时间:2014-05-07 06:30:13

标签: sed

我使用sed命令在第一次出现关键字后替换行。 当我找到关键字时,我使用以下命令替换整行。

sed -i "/<port>/c<port>=$a" /root/output.txt

但我的档案就像

<namenode>
   <port>8080</port>
</namenode>
<derby>
   <port>5050</port>
</derby>

在这种情况下如果我运行上面的命令,它也将改变namenode的两个行端口和derby的端口。但 我想改变具体的路线。我会在<port>之后搜索<namenode>的第一次出现,因此它只会更改namenode的端口值而不是derby的端口值。 我正在使用上面的命令改变整行。 我希望我能得到这个问题的答案。

3 个答案:

答案 0 :(得分:2)

据我了解,您只想更改名为namenode的部分中的端口。在那种情况下:

sed -i "/<namenode>/,/<\/namenode>/ s/<port>[0-9]\+/<port>$a/" /root/output.txt

使用/<namenode>/,/<\/namenode>/会将替换命令的操作限制为第一行包含<namenode>且其最后一行包含</namenode>的行组。在该范围内,任何端口号都将替换为shell变量$a的值。

答案 1 :(得分:1)

以下是使用awk

的示例
a=9090
awk '/<namenode>/ {f=1} f && /<port>/ {$0="   <port>"new"</port>";f=0}1' new="$a" file
<namenode>
   <port>9090</port>
</namenode>
<derby>
   <port>5050</port>
</derby>

它只会将port后的namenode更改为存储在变量a中的值


工作原理:

awk '
/<namenode>/ {                  # If the line contains "<namenode>"
    f=1}                        # do set flag `f` to `1` (true)
f && /<port>/ {                 # If flag `f` is true and line contains "<port>"
    $0="   <port>"new"</port>"  # change line to new data
    f=0}                        # and reset flag `f`
1                               # Do default action (print the line)
' new=10 file                   # Read variable and the file

使用范围功能:

awk '/<namenode>/,/<\/namenode>/ {if (/<port>/) $0="   <port>"new"</port>"}1' new="$a" file

答案 2 :(得分:1)

sed -i "/^<namenode>/,/<\/namenode>/ {
   /<port>/c<port>=$a
   }" /root/output.txt

封装到另一个块