我使用下面的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******
}
答案 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
并使用值RS
和RT
时,可以轻松完成此操作。
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;"
这意味着它在一行上,前面只有空格。如果此字符串不在记录中,请使用上一个和新记录分隔符RTO
和RT
打印它。
输出:
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>
/lease {/{:a;N;/}/!ba;
/\n *binding state free;/!p
d
此输出(间隔与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