文本数据/字符串的处理是Perl的强项
下面是一段 Oracle 的配置文件中的数据:
# tnsnames.ora Network Configuration File:
# c:\oracle\product\10.2.0\db_1\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.
PSDSS249 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =
10.136.33.249)(PORT =
1521))
)
(CONNECT_DATA =
(SERVICE_NAME =
PSDSS)
)
)
PSDSS248 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =
10.136.33.248)(PORT =
1521))
)
(CONNECT_DATA =
(SERVICE_NAME =
PSDSS)
)
)
FZJC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =
10.136.33.3)(PORT =
1521))
)
(CONNECT_DATA =
(SERVICE_NAME =
fzjc)
)
)
需要分析上述数据,提取 HOST/PORT/SERVICE_NAME 等信息,要求最后得到如下信息:
PSDSS249 10.136.33.249 1521 PSDSS
PSDSS248 10.136.33.248 1521 PSDSS
FZJC 10.136.33.3 1521 fzjc
#!/usr/bin/perl
use strict;
my (@data,@head);
my $stack_point = 0;
open(FILE, 'data.txt') or die $!;
$stack_point = -1;
while (<FILE>) {
my @characters = split(//);
for my $c (@characters) {
# 忽略空格或换行, 便于后面匹配
push(@data, $c) if ($c !~ /\s/);
push(@head, $c) if ($stack_point == -1 and $c !~ /\s/);
# 遇到左括弧 $stack_point 加 1,遇到右括弧则减 1
if ($c eq '(') { $stack_point++ }
elsif ($c eq ')') { $stack_point-- }
# $stack_point 为 0, 且 @head 有数据,表示读完一个记录头
if ($stack_point == 0 and @head) {
my $header = join('',@head);
$header =~ s/=.*$//;
print "$header\t";
@head = (); # 清空头
}
# $stack_point 计数为 -1 说明记录的数据读完
if ($stack_point == -1) {
my $line = join('',@data);
# 匹配并提取指定信息
if ($line =~ /HOST=(\S+)\)\(PORT=(\w+)\).*SERVICE_NAME=(\w+)\)/) {
print "$1 $2 $3 $4\n";
}
@data = (); # 清空数据
}
}
}
close FILE;
|
阅读(5107) | 评论(0) | 转发(0) |