我有一个文件格式如下:
pool1 {
name:$NAME
mode:$MODE
address:$ADDRESS
validity:$VALIDITY
}
pool2 {
name:$NAME
mode:$MODE
address:$ADDRESS
validity:$VALIDITY
}
pool3 {
name:$NAME
mode:$MODE
version:$VERSION
address:$ADDRESS
validity:$VALIDITY
}
我在另一个文件中有一个地址列表。虽然我遍历地址文件,但我需要在此文件中找到相应地址的名称。问题是池中的参数数量不固定,保持变化,如池3中显而易见的,其中一个名为version的新参数弹出.Hence我不能为地址执行正常的grep然后再次grep它上面的2行。我需要的是一个将搜索该事件的命令行“address:$ ADDRESS”,然后找到它之前发生的“name:$ NAME”..
答案 0 :(得分:2)
这是你要找的吗?
$ cat file
pool1 {
name:abc
mode:$MODE
address:foo
validity:$VALIDITY
}
pool2 {
name:defghi
mode:$MODE
address:stuff
validity:$VALIDITY
}
pool3 {
name:some other name
mode:$MODE
version:$VERSION
address:bar
validity:$VALIDITY
}
$
$ cat tst.awk
BEGIN { RS=""; FS="\n" }
{
split("",name2val) # or delete(name2val) with gawk
for (i=1;i<=NF;i++) {
line = $i
gsub(/^[[:space:]]+|[[:space:]]+$/,"",line)
if ( split(line,tmp,/:/) == 2 ) {
name2val[tmp[1]] = tmp[2]
}
}
if ( name2val["address"] == tgt ) {
print name2val["name"]
}
}
$
$ awk -v tgt="stuff" -f tst.awk file
defghi
如果没有使用更好的示例和预期输出更新您的问题。
答案 1 :(得分:1)
您可以将范围模式与awk一起使用,并且如果name
匹配,则在每个范围内打印address
。当然可以使用-v
awk -vaddress=address3 '/pool.*\{/,/\}/{if ($0 ~ /name/)name=$0;
if($0 ~ address) print name}' file.txt
答案 2 :(得分:1)
这可能会让你开始:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $infile = 'in.txt';
open my $input, '<', $infile or die "Can't open to $infile: $!";
my (@pool, @address, @name, %hash);
while (<$input>){
chomp;
push @pool, $1 if ($_ =~ /(pool\d+)\s+\{/g);
push @address, $1 if ($_ =~ /address:(.+)/g);
push @name, $1 if ($_ =~ /name:(.+)/g);
}
push @{$hash{$pool[$_]} }, [$address[$_], $name[$_] ] for 0 .. $#pool;
print Dumper \%hash;
它为您提供了数组的哈希:
$VAR1 = {
'pool1' => [
[
'$ADDRESS',
'$NAME'
]
],
'pool2' => [
[
'$ADDRESS',
'$NAME'
]
],
'pool3' => [
[
'$ADDRESS',
'$NAME'
]
]
};
现在,您可以读入包含地址的文件,并检查它们是否存在于上面的哈希
中答案 3 :(得分:1)
似乎一个好的开始就是打印你感兴趣的游泳池,这对于awk
来说是微不足道的。例如:
awk '/\n address:pattern/' RS= input-file
只会打印地址与pattern
匹配的池。通过将RS设置为空字符串,awk
将段落(由空行分隔的文本块)视为单个记录。在理想的世界中,awk将该记录重新分析为字典并打印名称会很简单,但将输出传递给另一个awk
非常简单:
awk '/\n address:pattern/' RS= input-file | awk '/^ name/'