Разделить одну длинную строку из текстового файла на несколько строк (CSV) - PullRequest
1 голос
/ 26 октября 2019

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

Я попробовал приведенный ниже код, и, хотя он разделяет строки наполовину, данные не разбиваются на массивы.

open (INPUT, '<', $proxy_file ) or die "Cannot open proxy file\n";
open(OUTPUT, '>', $complete) or die "Cannot create $complete.'\n'";
while(my $line = <INPUT>){
    chomp $line;
    $line =~ s/,//g;
    $line =~ s/://g;
    my @fields = split /(?<=\.com)/, $line;

    print OUTPUT $_, "\n" for @fields;

Это пример данных

JACOB2345@gmail.com:YdjfkoweU, LUKE453@gmail.com:YdjfkoweU, WESLEY233@gmail.com:YdjfkoweU, Bruce2423@gmail.com:YdjfkoweU, Angel@gmail.com:YdjfkoweU, Lukder@gmail.com:YdjfkoweU, 

Я хочу разделить его на:

FIELD 1             FIELD2
JACOB2345@gmail.com YdjfkoweU
LUKE453@gmail.com YdjfkoweU

и т. Д.

Ответы [ 3 ]

2 голосов
/ 26 октября 2019

Этот код выделит вам CSV:

use strict;
use warnings;

my $line = 'JACOB2345@gmail.com:YdjfkoweU, LUKE453@gmail.com:YdjfkoweU, WESLEY233@gmail.com:YdjfkoweU, Bruce2423@gmail.com:YdjfkoweU, Angel@gmail.com:YdjfkoweU, Lukder@gmail.com:YdjfkoweU';

print "Field 1\tField 2\n";

foreach my $rec (split(/,\s*/,$line)) {
    chomp($rec);
    $rec =~ s/:/\t/;

    print $rec,"\n";
}
1 голос
/ 26 октября 2019
use strict;
use warnings;

while(my $line = <DATA>) {
  chomp($line);
  my @rows = split/,\s{1}/, $line;
  foreach my $row (@rows) {
    my ($field_1, $filed_2) = split/:/, $row;
    print "$field_1<=>$filed_2\n";
  }
}



__DATA__
JACOB2345@gmail.com:YdjfkoweU, LUKE453@gmail.com:YdjfkoweU, WESLEY233@gmail.com:YdjfkoweU, Bruce2423@gmail.com:YdjfkoweU, Angel@gmail.com:YdjfkoweU, Lukder@gmail.com:YdjfkoweU,
0 голосов
/ 27 октября 2019

Попробуйте вместо этого простой perl-однострочный (ну, почти однострочный) вместо этого:

echo 'JACOB2345@gmail.com:YdjfkoweU, LUKE453@gmail.com:YdjfkoweU, WESLEY233@gmail.com:YdjfkoweU, Bruce2423@gmail.com:YdjfkoweU, Angel@gmail.com:YdjfkoweU, Lukder@gmail.com:YdjfkoweU, ' | \
    perl -F'/,\s*/' -lane '
BEGIN {
    $out_rec_sep = "\t";
    print join $out_rec_sep, map { "FIELD$_" } (1..2);
}
foreach $rec ( @F ) {
    print join $out_rec_sep, split m{:}, $rec;
}'

Печать в STDOUT (который можно перенаправить в файл, используя > out_file):

FIELD1  FIELD2
JACOB2345@gmail.com     YdjfkoweU
LUKE453@gmail.com       YdjfkoweU
WESLEY233@gmail.com     YdjfkoweU
Bruce2423@gmail.com     YdjfkoweU
Angel@gmail.com YdjfkoweU
Lukder@gmail.com        YdjfkoweU

Если вам нужен вывод csv (через запятую) вместо вывода tsv (через табуляцию), выберите $out_rec_sep = ",";.

В вашем коде есть несколько проблем.

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

Ваш метод использования регулярных выражений для удаления разделителей и последующего разделения на .com приводит к более длинному и более запутанному коду (избавляется от структуры ввода с 2 разделителями), склонен к ошибкам (как вы заметили) и не устойчив к изменениям во входных данных (подумайте, заканчиваются ли некоторые электронные письма .edu, .org и т. д.?).

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