【发布时间】:2016-01-05 20:32:45
【问题描述】:
我想搜索一个字符串并将其从块中删除。我尝试使用sed 和awk,但我无法弄清楚。
让积木变成这样:
[MAIN]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
[sub]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
我需要进入 Main 块并通过搜索删除 three=[4] 。
【问题讨论】:
我想搜索一个字符串并将其从块中删除。我尝试使用sed 和awk,但我无法弄清楚。
让积木变成这样:
[MAIN]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
[sub]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
我需要进入 Main 块并通过搜索删除 three=[4] 。
【问题讨论】:
使用awk 和null 记录分隔符:
awk -v RS= -v ORS='\n\n' '/\[MAIN\]/{sub(/three=\[ab12\][[:space:]]*/, "")} 1' file
[MAIN]
one=[1]
two=[2]
three=[4]
three=[5]
[sub]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
【讨论】:
/three=\[[^\]]*\][[:space:]]*/ 将匹配 three[ 和 ] 之间的任何内容。所以所有three=[123] three=[acb] three=[ab12]都会被匹配并删除。
Perl 版本:
% perl -pe'BEGIN { $/ = "\n\n" } if (/\A\[MAIN\]/) { s/^three=\[4\]\n//m }' file
将输出:
[MAIN]
one=[1]
two=[2]
two=[3]
three=[5]
[sub]
one=[1]
two=[2]
three=[3]
three=[4]
three=[5]
顺便说一句,如果这是 INI 格式,您可能还想为此使用更合适的 INI 解析器。例如,以下是使用 Config::IOD 的方法:
use Config::IOD;
my $iod = Config::IOD->new;
my $doc = $iod->read_file("file");
$doc->delete_key({
all => 1,
cond => sub{
my ($self, %args) = @_;
return 1 if $args{raw_value} =~ /4/;
},
"MAIN","three"
);
print $doc->as_string;
如果键的值包含“4”,上面的代码将删除“MAIN”部分下的所有“三个”键行。您可以根据需要调整代码。
【讨论】:
这可能对你有用(GNU sed):
sed '/\[MAIN\]/,/^$/!b;/three=\[4\]/d' file
如果它不在[MAIN] 块内,则视为正常。否则删除匹配的行。
【讨论】: