Как я могу извлечь столбцы данных с помощью Perl? - PullRequest
1 голос
/ 23 августа 2010

У меня есть строки такого типа

NAME1              NAME2          DEPTNAME           POSITION
JONH MILLER        ROBERT JIM     CS                 ASST GENERAL MANAGER 

Я хочу, чтобы вывод был name1 name2 и позиционировал, как я могу сделать это, используя split / regex / trim / etc и без использования модулей CPAN?

Ответы [ 6 ]

6 голосов
/ 23 августа 2010

Это будет зависеть от того, являются ли они полями фиксированной длины, или они разделены табуляцией.Самый простой (с использованием split), если они разделены табуляцией.

my ($name1, $name2, $deptName, $position) = split("\t", $string);

Если они фиксированной длины и, если они все, скажем, длиной 10 символов, вы можете проанализировать его как

my ($name1, $name2, $deptName, $position) = unpack("A10 A10 A10 A10", $string);
2 голосов
/ 23 августа 2010

Если ваши входные данные поступают в виде массива строк (@strings), это

for my $s (@strings) {
   my $output = join ' ',
                map /^\s*(.+)\s*$/ ? $1 : (),
                unpack('A19 A15 x19 A*', $s);
   print "$output\n"
}

извлечет и обрезает необходимую информацию.

NAME1 |ИМЯ2 |ПОЗИЦИЯ

и

JONH MILLER |РОБЕРТ ДЖИМ |ГЕНЕРАЛЬНЫЙ МЕНЕДЖЕР ASST

(я добавил '' 'для лучшего увеличения результата)

С уважением

rbo

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

Из этого примера в данных содержится один пробел, а 2 или более смежных - нет. Таким образом, вы можете легко разделить на 2 или более пробелов. Единственное, что я добавлю к этому, это использование List::MoreUtils::mesh

use List::MoreUtils qw<mesh>;
my @names   = map { chomp; $_ } split /\s{2,}/, <$file>;
my @records = map { chomp; { mesh( @names, @{[ split /\s{2,}/ ]} ) } } <$file>;
1 голос
/ 23 августа 2010

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

#!/usr/bin/perl
use strict;
use warning;
my $string = "NAME1              NAME2          DEPTNAME           POSITION
             JONH MILLER        ROBERT JIM     CS                 ASST GENERAL MANAGER ";
my @string_parts = split /\s\s+/, $string;
foreach my $test (@string_parts){  
      print"$test\n";
}
0 голосов
/ 23 августа 2010

Подумайте об использовании автоматического разделения в однострочнике Perl из командной строки:

$ perl -F/\s{2,}/ -ane 'print qq/@F[0,1,3]\n/' file

Однострочник разделится на два или более последовательных пробела и напечатает первое, второе и четвертое поля, соответствующиеПоля NAME1, NAME2 и POSITION.

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

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

Чтобы разделить на пустое пространство:

@string_parts = split /\s{2,}/, $string;

Это разделит $string на список подстрок. Разделителем будет регулярное выражение \s+, что означает один или несколько пробельных символов . Сюда входят пробелы, табуляции и (если я не ошибаюсь) переводы строк.

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

...