字符串案例中的sed匹配问题与“\<>”?

时间:2018-03-23 10:38:14

标签: linux bash shell awk sed

我使用下面的sed脚本删除了一些与

匹配的内容块

“绑定状态自​​由;”

字符串,但问题是在某些块中我有字符串

“下一个绑定状态免费”

以下命令认为它是一个匹配并删除它我也不想删除“下一个绑定状态免费”块plz建议。

并从输入文件中删除“绑定状态释放”块。

  sed -e '/lease/!b;:a;/}/!{$!{N;ba}};{/\<binding state free;\>/d}' file.txt

我正在使用此命令,但它也删除了“下一个绑定状态免费”

块数据sed将其视为匹配,因为它还包含“绑定状态自​​由”;字符串。

lease {

    *****some text******
      binding state free;
      *****some text******
      *****some text******
    }
    lease {
      *****some text******
      *****some text******
      binding state free;
      *****some text******
      *****some text******
    }
    lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }
    lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }

期望的输出: -

lease {
          *****some text******
          *****some text******
          binding state active;
          next binding state free;
          rewind binding state free;
          *****some text******
          *****some text******
        }
        lease {
          *****some text******
          *****some text******
          binding state active;
          next binding state free;
          rewind binding state free;
          *****some text******
          *****some text******
        }

3 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -n '/lease {/{:a;N;/}/!ba;/^\s*binding state free;\s*$/M!p}' file

使用类似grep的选项-n仅打印所需内容。收集lease {}之间的行。如果集合中的任何一行包含binding state free而没有其他内容,请不要打印该集合。

N.B。使用M多行标志来定制正则表达式。

答案 1 :(得分:1)

当您使用GNU awk并使用值RSRT时,可以轻松完成此操作。

  

RS 输入记录分隔符。它的默认值是一个字符串   包含单个换行符,表示输入   记录由单行文本组成。它也可以是null   string,在这种情况下,记录由空行的分隔。如果   它是一个正则表达式,记录由正则表达式的匹配分隔   输入文本。 (见Records。)

     

(gawk extention) RS成为正则表达式的能力是gawk扩展名。在   大多数其他awk实现,或者如果gawk处于兼容模式   (参见Options),只使用RS值的第一个字符。

     

RT(gawk extention)与表示的文字相匹配的输入文字   RS,记录分隔符。每次读取记录时都会设置它。

awk 'BEGIN { RS="lease *{|}" }
     (RT=="}") && (!/\n *binding state free;/)){ print RTO $0 RT }
     {RTO=RT}' <file>

此脚本将记录分隔符RS设置为等于lease {}。 如果是RT=="}",那么我们通过检查所请求的字符串是否存在来处理记录。字符串本身应该是"\n *binding state free;"这意味着它在一行上,前面只有空格。如果此字符串不在记录中,请使用上一个和新记录分隔符RTORT打印它。

输出:

lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }
lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }

如果您想在sed中执行此操作,我会采用略有不同的方法。

sed '/lease {/ {:a;N;/}/!ba;/\n *binding state free;/!p; };d;' <file>
  1. 使用/lease {/{:a;N;/}/!ba;
  2. 阅读完整记录
  3. 使用/\n *binding state free;/!p
  4. 处理记录
  5. 删除模式空间d
  6. 此输出(间隔与awk略有不同):

       lease {
          *****some text******
          *****some text******
          binding state active;
          next binding state free;
          rewind binding state free;
          *****some text******
          *****some text******
        }
        lease {
          *****some text******
          *****some text******
          binding state active;
          next binding state free;
          rewind binding state free;
          *****some text******
          *****some text******
        }
    

答案 2 :(得分:0)

我相信你能在sed做到这一点,但这个想法吓坏了我。我会推荐一个awk脚本:

# match start of block
$1 == "lease" {
    n = 1
    should_print = 1
}

# save every line in the buffer
{
    buffer[n++] = $0
}

# unset the print flag if text is matched
/^[[:blank:]]*binding state free;[[:blank:]]*$/ {
    should_print = 0
}

# match end of block
$1 == "}" && should_print {
    for (i = 1; i < n; ++i) {
        print buffer[i]
    }
}

在输入上测试它:

$ awk -f script.awk file
    lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }
    lease {
      *****some text******
      *****some text******
      binding state active;
      next binding state free;
      rewind binding state free;
      *****some text******
      *****some text******
    }

如果您对输出感到满意,可以使用标准方法覆盖输入:

awk -f script.awk file > tmp && mv tmp file