将名称映射到perl中的文件名

时间:2010-08-05 05:49:38

标签: perl

我现在很困惑...... 这是我的问题: 我有一个这种格式的文本文件

Tom                 //name
Washington 
account.txt             //filename
Gary                    //NAME
New York
accountbalance.png      //filename
Mary                    //name
New Jersey             
Michelle               //NAME
Larry                  //NAME
Charles                //NAME  
Washington
Real.cpp               //FILENAME
.
.goes on(large file)

我想提取名称和相应的文件名。例如,Charles是使用real.cpp工作的人的名字....

我想我需要

  1. 使用while循环
  2. 在其中使用了两个if语句(一个用于提取其他名称以提取filenmae)
  3. 结束while循环
  4. 面临的问题:我得到与其不对应的名称和文件名...(由于文本文件读取中没有一对一关系的不一致) 我希望名称是键和文件名作为值并将其存储在哈希中 如何解决这个......我很困惑。给我建议,请

5 个答案:

答案 0 :(得分:1)

如果名称后面总是有//name,文件名后面总是有//filename,文件名前的名称就是与文件名关联的名称,这很简单:

#!/usr/bin/perl

use strict;
use warnings;

my $key;
my %name_to_filename;
while (<DATA>) {
    #only pay attention to lines that have //name or //filename
    #and save off the part before //name or //filename and which type it was
    next unless my ($name, $type) = m{(.*?)\s+//(name|filename)}i;
    if ($type =~ /^name$/i) {
        $key = $name; #remember the last name seen
        next;
    }
    $name_to_filename{$key} = $name;
}

use Data::Dumper;
print Dumper \%name_to_filename;

__DATA__
Tom                 //name
Washington
account.txt             //filename
Gary                    //NAME
New York
accountbalance.png      //filename
Mary                    //name
New Jersey
Michelle               //NAME
Larry                  //NAME
Charles                //NAME
Washington
Real.cpp               //FILENAME

答案 1 :(得分:0)

有3个变量 LINE_1,LINE_2,Current_line。 对于前两行读取变量Line_1,Line_2被初始化。 现在读取第3行时检查它是否为File      如果是,则将其存储在散列哈希{filename} = name,city中。      如果不是,则将Line_2复制到Line_1,将Current_line复制到Line_2。 这个shuld发生在循环中直到读完整个文件

答案 2 :(得分:0)

因为您要将名称映射到文件名。数据显示您获得了一个列表 的名称,然后是文件名。因此,您需要存储密钥,直到 你知道你可以存储它们。

此外,由于你没有对州名说什么,我希望你想要 忽略那些。所以我们需要一种方法来区分它们。幸运的是,各州都是 一个定义良好的集合,可以放入查找表中。

然后,我们需要一种方法来区分名称和文件名,以及你展示的内容,我是 使用以下模式:至少一个单词字符,然后单个点, 然后至少有一个单词字符用于扩展。

这样会告诉我我们是否在文件行上,并且可以解析该值 待定名称。

@ARGV = '/path/to/file';

my %state_hash
    = ( Alabama => 1, Alaska => 1, Arizona => 1, ...
      , 'New Hampshire' => 1, ..., Wyoming => 1
      );

my ( @pending_names, %file_for );
while ( <> ) { 
    # Extract non-spaces at the beginning of the line
    # potentially separated with one-and-only-one space
    my ( $name_or_file ) = m/^(?:\S+[ ]?)+)/;
    next unless $name_or_file or exists $state_hash{ $name_or_file };

    # if the extract value fits the file pattern
    if ( $name_or_file =~ m/^\w+\.\w+$/ ) { 
        # store the name-file combination for each pending
        $file_for{ $_ } = $name_or_file foreach @pending_names;
        # they are not pending anymore, so clear them.
        @pending_names  = ();
    }
    else { 
        # store up pending names
        push @pending_names, $name_or_file;
    }
}

你没有要求处理的是,它是一个“大文件”,一个名字 可能会重演。如果一个名称不止一次重复,你就会破坏这个价值 你上次保存。

这可以通过push补救 - 进入散列槽而不是简单地分配它。像这样:

push @{ $file_for{ $_ } }, $name_or_file foreach @pending_name;

答案 3 :(得分:0)

此版本使用名为%is_city的哈希来跳过看起来像城市的行,并假设包含.的名称是文件名。但这两种假设都很糟糕。例如,我的名字包含一个句号,像麦迪逊这样的名字可以是一个城市或一个人的名字。

#!/usr/bin/perl

use strict;
use warnings;

my %is_city = map { $_ => 1 } (
    "Washington", "New York", "New Jersey",
);

my $key;
my %name_to_filename;
while (my $name = <DATA>) {
    chomp $name;
    next if $is_city{$name};
    if ($name =~ /[.]/) {
        $name_to_filename{$key} = $name;
        next;
    }
    $key = $name;
}

use Data::Dumper;
print Dumper \%name_to_filename;


__DATA__
Tom
Washington
account.txt
Gary
New York
accountbalance.png
Mary
New Jersey
Michelle
Larry
Charles
Washington
Real.cpp

答案 4 :(得分:0)

假设所有文件名中都包含.,并且该文件名是唯一的文件名。

同时假设城市和州的名单太大而无法获得整个清单。

#! /usr/bin/env perl
use strict;
use warnings;

my @state_city_or_person;
my %files;

while(<>){
  chomp;
  if( index($_,'.') >= 0 ){
    push @{ $files{$_} }, @state_city_or_person;
    @state_city_or_person = ();
  }else{
    push @state_city_or_person, $_;
  }
}

use YAML;

print Dump \%files;
---
Real.cpp:
  - Mary
  - New Jersey
  - Michelle
  - Larry
  - Charles
  - Washington
account.txt:
  - Tom
  - Washington
accountbalance.png:
  - Gary
  - New York

您仍然需要通过并删除任何无关的数据,例如城市和州,但这可以帮助您将其转换为实际的可解析格式。

如果数据的某种结构开始,将会很有帮助。