Отображение имени на имя файла в Perl - PullRequest
0 голосов
/ 05 августа 2010

я сейчас в замешательстве ... Вот моя проблема: у меня есть текстовый файл в этом формате

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)

Я хотел извлечь имя и соответствующее имя файла. Например, Чарльз - это имячеловек, который работал над real.cpp ....

Я думаю, мне нужно

  1. использовать цикл while
  2. использовал два оператора if внутри него (один дляизвлечь имя другое, чтобы извлечь filenmae)
  3. завершить цикл while

Возникла проблема: я получаю имена и имена файлов, которые не соответствуют ему ... (из-за отсутствия неправильности одногок одному отношению в чтении текстового файла) Я хочу, чтобы имя было ключом, а имя файла - значением, и сохраните его в хэше. Как решить эту проблему ..... Я в замешательстве .. Дайте мне предложения, Pls

Ответы [ 5 ]

1 голос
/ 05 августа 2010

Если за именами всегда следует //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
0 голосов
/ 12 августа 2010

Предполагая, что во всех именах файлов есть ., и что имена файлов - это то, что делает only .

Также предполагается, что список городов и состояний настолько великчтобы было невозможно получить полный список.

#! /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

Вам все равно придется просмотреть и удалить любые посторонние данные, такие как города и штаты, но это должно помочь вам получить их вфактический анализируемый формат.

Было бы полезно, если бы существовала какая-то структура данных для начала.

0 голосов
/ 05 августа 2010

Эта версия использует хеш с именем %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
0 голосов
/ 05 августа 2010

Так как вы хотите сопоставить имена с именем файла. Данные показывают, что вы получаете список имен, а затем имя файла. Таким образом, вам нужно будет хранить ключи до Вы знаете, что вы можете хранить их.

Кроме того, поскольку вы ничего не сказали о названиях штатов, я думаю, вы хотите игнорировать их. Поэтому нам нужен способ отличить их друг от друга. К счастью, штаты четко определенный набор, и может быть помещен в таблицу поиска.

Тогда нам нужен способ отличить имена от имен файлов, от того, что вы показываете, я идя по следующему шаблону: по крайней мере, один символ слова, затем одна точка, затем хотя бы один символ слова для расширения.

Так что это скажет мне, находимся ли мы в строке файла, и может разрешить значение из ожидающих имен.

@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;
0 голосов
/ 05 августа 2010

есть 3 переменные Line_1, Line_2, Current_line. Для первых двух строк прочитайте переменные Line_1, Line_2 инициализированы. Теперь при чтении 3-й строки проверьте, является ли это файлом Если да, то сохраните то же самое в хэше {имя файла} = имя, город. Если нет, скопируйте Line_2 в Line_1 и Current_line в Line_2. Это должно происходить в цикле, пока весь файл не будет прочитан

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...