使用Perl读取非分隔文本文件
我有一个文件,它有一个标准的输入,但它的形式我以前从未尝试读入Perl程序 该文件的格式如下:使用Perl读取非分隔文本文件,perl,Perl,我有一个文件,它有一个标准的输入,但它的形式我以前从未尝试读入Perl程序 该文件的格式如下: 净数量分配 编号xxx.xxx.xxx.xxx 表30中的网络掩码 类型IP 使用状态 说明mpirpd cjdn 票据管理 条目Id 0000000000 26450 提交人约翰·多伊 创建日期2009-07-01-13:55:24 内部联系方式/555-555-5555 联系人Id CON-000028508 净分配数 编号xxx.xxx.xxx.xxx 格式32中的网络掩码 类型IP 使用状态
净数量分配
编号xxx.xxx.xxx.xxx
表30中的网络掩码
类型IP
使用状态
说明mpirpd cjdn
票据管理
条目Id 0000000000 26450
提交人约翰·多伊
创建日期2009-07-01-13:55:24
内部联系方式/555-555-5555
联系人Id CON-000028508
净分配数
编号xxx.xxx.xxx.xxx
格式32中的网络掩码
类型IP
使用状态
说明开关Lo0--开关未命名
Lan管理环回和链路的注释
条目Id 0000000000 32710
提交人约翰·多伊
创建日期2015-11-25-10:59:27
最后由JohnDoe修改
修改日期2015-11-25-11:30:06
内部联系方式/555-555-5555
联系人Id CON-000028508
净分配数
编号xxx.xxx.xxx.xxx
格式32中的网络掩码
类型IP
使用状态
说明mplsfe9集线器
区域mpls
条目Id 0000000000 24150
提交人Russ Reilly
创建日期2007-05-02-18:26:20
最后由JohnDoe修改
修改日期2013-05-06-19:09:37
联系人姓名ITG内部
联系电话555-555-5555
联系电子邮件me@home.com
并非总是使用所有字段(例如:联系人姓名和联系人电话可能在下一条记录中丢失)
我不一定需要字段标题,因为它们始终位于每个记录的相同位置
我相信这是以前做过的,可能有一个简单的解决方案,所以在我重新创建轮子之前,我会问这个问题 这在概念上很简单,但有点乏味。此类解析解决方案的规范版本如下所示:
#!/usr/bin/perl
my $all = {}; # A hash to hold all number entries indexed by IP
my $cur = {}; # A hash to hold the current entry we are parsing
while(<>)
{
chomp;
if (my ($ip) = /^Number\s+(.*)/)
{
# If we have a current entry, save it in the $all hash
$all->{$cur->{number}} = $cur if ($cur->{number});
$cur = {};
$cur->{number} = $ip;
}
elsif (my ($mask) = /^Netmask in \/## Form\s+(\d+)/)
{
$cur->{mask} = $mask;
}
elsif ... # Handle remaining input line types, saving what you want in $cur
}
# This is to save the last entry
$all->{$cur->{number}} = $cur if ($cur->{number});
# Your code to process the accumulated entries
...
#/usr/bin/perl
我的$all={};#用于保存由IP索引的所有数字项的哈希
我的$cur={};#用于保存我们正在分析的当前项的哈希
while()
{
咀嚼;
如果(我的($ip)=/^Number\s+(.*)/)
{
#如果有当前条目,请将其保存在$all散列中
$all->{$cur->{number}}=$cur if($cur->{number});
$cur={};
$cur->{number}=$ip;
}
elsif(my($mask)=/^Netmask,格式为\/##\ s+(\d+/)
{
$cur->{mask}=$mask;
}
elsif…#处理剩余的输入行类型,将所需内容保存在$cur中
}
#这是为了保存最后一个条目
$all->{$cur->{number}}=$cur if($cur->{number});
#处理累积条目的代码
...
这在概念上很简单,但有点乏味。此类解析解决方案的规范版本如下所示:
#!/usr/bin/perl
my $all = {}; # A hash to hold all number entries indexed by IP
my $cur = {}; # A hash to hold the current entry we are parsing
while(<>)
{
chomp;
if (my ($ip) = /^Number\s+(.*)/)
{
# If we have a current entry, save it in the $all hash
$all->{$cur->{number}} = $cur if ($cur->{number});
$cur = {};
$cur->{number} = $ip;
}
elsif (my ($mask) = /^Netmask in \/## Form\s+(\d+)/)
{
$cur->{mask} = $mask;
}
elsif ... # Handle remaining input line types, saving what you want in $cur
}
# This is to save the last entry
$all->{$cur->{number}} = $cur if ($cur->{number});
# Your code to process the accumulated entries
...
#/usr/bin/perl
我的$all={};#用于保存由IP索引的所有数字项的哈希
我的$cur={};#用于保存我们正在分析的当前项的哈希
while()
{
咀嚼;
如果(我的($ip)=/^Number\s+(.*)/)
{
#如果有当前条目,请将其保存在$all散列中
$all->{$cur->{number}}=$cur if($cur->{number});
$cur={};
$cur->{number}=$ip;
}
elsif(my($mask)=/^Netmask,格式为\/##\ s+(\d+/)
{
$cur->{mask}=$mask;
}
elsif…#处理剩余的输入行类型,将所需内容保存在$cur中
}
#这是为了保存最后一个条目
$all->{$cur->{number}}=$cur if($cur->{number});
#处理累积条目的代码
...
我建议使用哈希数组作为您所展示文件的理想数据结构
我们将设置为”
,将两个或多个连续的空行视为一个空行。然后,在每个记录中,我们只需将每行拆分为两个或多个空格,这将保留包含空格的键。拆分
限制为总共2个字段,以防止为包含两个或多个连续空格的值创建其他字段(例如,ITG INTERNAL
)
我建议使用散列数组作为您提供的文件的理想数据结构
我们将设置为”
,将两个或多个连续的空行视为一个空行。然后,在每个记录中,我们只需将每行拆分为两个或多个空格,这将保留包含空格的键。拆分
限制为总共2个字段,以防止为包含两个或多个连续空格的值创建其他字段(例如,ITG INTERNAL
)
您试图将这些数据解析成什么样的结构?通常我会使用数组进行哈希运算。在这种情况下,我的密钥将是数字字段,该字段在整个文件中应该是唯一的,数组将是在下一个数字字段之前的字段。因此,您想使用该字段处理许多文件吗?每个都将使用数组ref填充自己的数字键?(如果它有一个hash ref,由字段名键入,可能更可读。)如果它是一个数组,您可以将。。。当没有此类记录时,是否为零/空字符串?这应该(相对)简单,你试过什么吗?它不起作用了吗?或者你不知道怎么做?是你在一个文件中显示的内容,还是你在显示多个(3)文件?是否每一节“网络编号Ass…”都有自己的(唯一)编号?这是一个文件中3条记录的样本。该文件实际上包含1000条记录。您试图将这些数据解析成什么样的结构?通常我会使用数组进行哈希运算。在这种情况下,我的密钥将是数字字段,该字段在整个文件中应该是唯一的,数组将是在下一个数字字段之前的字段。因此,您想使用该字段处理许多文件吗?每个都将使用数组ref填充自己的数字键?(如果它有一个hash ref,由字段名键入,可能更可读。)如果它是一个数组,您可以将。。。当没有此类记录时,是否为零/空字符串?这应该(相对)简单,你试过什么吗?它不起作用还是不起作用
[
{
"Contact-Data" => "INTERNAL/555-555-5555",
"Contact-Id" => "CON-000028508",
"Create-date" => "2009-07-01-13:55:24",
"Description" => "mpirpd-cjdn",
"Entry-Id" => "000000000026450",
"Netmask in /## Form" => 30,
"Notes" => "mgmt",
"Number" => "xxx.xxx.xxx.xxx",
"Status" => "InUse",
"Submitter" => "John Doe",
"Type" => "IP",
},
{
"Contact-Data" => "INTERNAL/555-555-5555",
"Contact-Id" => "CON-000028508",
"Create-date" => "2015-11-25-10:59:27",
"Description" => "switch Lo0 -- switch unnamed",
"Entry-Id" => "000000000032710",
"Last-modified-by" => "John Doe",
"Modified-date" => "2015-11-25-11:30:06",
"Netmask in /## Form" => 32,
"Notes" => "Reverved for Lan Management Loop Backs and links",
"Number" => "xxx.xxx.xxx.xxx",
"Status" => "InUse",
"Submitter" => "John Doe",
"Type" => "IP",
},
{
"Area" => "mpls",
"Contact E-mail" => "me\@home.com",
"Contact Name" => "ITG INTERNAL",
"Contact Phone" => "555-555-5555",
"Create-date" => "2007-05-02-18:26:20",
"Description" => "mplsfe9-hub",
"Entry-Id" => "000000000024150",
"Last-modified-by" => "John Doe",
"Modified-date" => "2013-05-06-19:09:37",
"Netmask in /## Form" => 32,
"Number" => "xxx.xxx.xxx.xxx",
"Status" => "InUse",
"Submitter" => "Russ Reilly",
"Type" => "IP",
},
]