【问题标题】:Match two lines, replace with three lines匹配两行,替换为三行
【发布时间】:2016-02-25 12:13:14
【问题描述】:

我需要使用sed每个 匹配的两行模式替换为三行模式。这是我的输入文件 (tempfile.txt)。

lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

基本上,如果client-hostname "HOSTNAME"; 缺少,则应将其替换为 tab,然后是 newline

我的尝试: sed 'N; /hardware.*}/d; P; D' tempfile.txt

结果是:

lease 192.168.6.100 {
  binding state free;
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

这是我想要的输出。

lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
  <tab>
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
  <tab>
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

如您所见,卷曲之间始终存在三行。这就是我的目标。

【问题讨论】:

  • 我不太明白:“如果它丢失了,它应该被替换”......?你能显示所需的输出吗?
  • 你能把这个添加到问题中吗?
  • 我的意思是,edit 这个问题更清楚,对于未来的访问者也是如此,而无需深入研究 cmets。
  • 完成。对此感到抱歉。
  • 我已经编辑了这个问题:你实际上是用三行替换了两行匹配的行 - 我已经相应地更改了措辞。

标签: linux unix sed


【解决方案1】:

这可以解决问题(管道到cat -A 以显示不可打印的字符):

$ sed -r 'N;s/^([[:space:]]*hardware.*)(\n})$/\1\n\t\2/;t;P;D' infile | cat -A
lease 192.168.6.100 {$
  binding state free;$
  hardware ethernet 00:e0:4c:68:00:96;$
^I$
}$
lease 192.168.6.100 {$
  binding state active;$
  hardware ethernet 00:e0:4c:68:00:96;$
  client-hostname "andrew-H81M-S2PH";$
}$
lease 192.168.6.100 {$
  binding state free;$
  hardware ethernet 00:e0:4c:68:00:96;$
^I$
}$
lease 192.168.6.100 {$
  binding state active;$
  hardware ethernet 00:e0:4c:68:00:96;$
  client-hostname "andrew-H81M-S2PH";$
}$

这不是删除匹配项,而是捕获应该围绕空行的两行,并替换为之间的换行符和制表符。为了更安全地匹配,我还添加了一些锚点。

由于模式空间在替换后包含两个换行符,因此涉及一些技巧,但P;D 仅打印第一行并开始一个新循环,这会导致在包含client-hostname 的行之后也出现不需要的换行符。

更详细的解释:

N       # Append next line to pattern space

# If the hostname is missing, insert a newline and a tab
s/^([[:space:]]*hardware.*)(\n})$/\1\n\t\2/

t      # If we did the substitution, jump to end (prints complete pattern space)
P      # Print first line in pattern space
D      # Delete first line in pattern space - starts new cycle

【讨论】:

    【解决方案2】:

    我冒昧地添加了另一个卷曲......

    sed 'N; s/hardware.*}/\t\n}/; P; D' andy
    lease 192.168.6.100 {
      binding state free;
    
    }
    lease 192.168.6.100 {
      binding state active;
      hardware ethernet 00:e0:4c:68:00:96;
      client-hostname "andrew-H81M-S2PH";
    }
    lease 192.168.6.100 {
      binding state free;
    
    }
    lease 192.168.6.100 {
      binding state active;
      hardware ethernet 00:e0:4c:68:00:96;
      client-hostname "andrew-H81M-S2PH";
    }
    

    【讨论】:

    • 抱歉,在我意识到我最初的问题问错之前,您的回答是正确的。道歉!
    猜你喜欢
    • 2013-12-26
    • 2021-06-02
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2012-09-13
    • 2011-06-30
    • 2020-04-16
    • 1970-01-01
    相关资源
    最近更新 更多