Как отфильтровать столбцы из файла CSV по именам столбцов - PullRequest
0 голосов
/ 04 октября 2018

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

Я не нашел ни одного подходящего метода в Text CSV.Пожалуйста, дайте мне знать, если какой-либо метод или модуль доступен

UniqueId, Name, description, user,timestamp     
1,jana,testing,janardar,12-10-2018:00:
sub _filter_common_columns_from_csv{

    my $csvfile = shift;
    my $CSV = Text::CSV_XS->new(
                                {
                                    binary => 1,
                                    auto_diag => 3,
                                    allow_quotes => 0,
                                    eol => $/ 
                                });
    my $_columns ||= do {
    open(my $fh, '<', $csvfile) or die $!;
    my @cols = @{ $CSV->getline($fh) };
    close $fh or die $!;
    for (@cols) { s/^\s+//; s/\s+$//; }
        \@cols;
    };
    my @columns = @{ $_columns };     
    my %deleted;                        
    my @regexes = qw(user timestamp);
    foreach my $regex (@regexes) {
            foreach my $i (0 .. ($#columns - 1)) {
                    my $col = $columns[$i];
                       $deleted{$i} = $col if $col =~ /$regex/;
            }
    }

    my @wanted_columns = grep { !$deleted{$_} } 0 .. $#columns - 1;
    my $input_temp = "$ENV{HOME}/output/temp_test.csv";


    open my $tem, ">",$input_temp or die "$input_temp: $!";

    open(my $fh, '<', $csvfile) or die $!;

    while (my $row = $CSV->getline($fh)) {
           my @fields = @$row;
              $CSV->print($tem, [ @fields[@wanted_columns] ]) or $CSV->error_diag;
    }
    close $fh or die $!;
    close $tem or die $!;

    return $input_temp;
}

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

См. getline_hr

use warnings;
use strict;
use feature 'say';

use List::MoreUtils qw(any);
use Text::CSV;

my $file = shift @ARGV || die "Usage: $0 filename\n";

my @exclude_cols = qw(user timestamp);

my $csv = Text::CSV->new ( { binary => 1 } ) 
    or die "Cannot use CSV: ".Text::CSV->error_diag (); 

open my $fh, '<', $file or die "Can't open $file: $!";

my @cols  = @{ $csv->getline($fh) };

my @wanted_cols = grep { 
    my $name = $_; 
    not any { $name eq $_ } @exclude_cols;
} @cols;

my $row = {}; 
$csv->bind_columns (\@{$row}{@cols});

while ($csv->getline($fh)) {
    my @wanted_fields = @$row{ @wanted_cols };
    say "@wanted_fields";
}

Синтаксис @$row{@wanted_cols} для хэша slice , который возвращает список значений для ключей в @wanted_colsиз хешрефа $row.

0 голосов
/ 05 октября 2018

Если вы хотите изменить CSV и другими способами, и если SQL будет удобен для этих модификаций, подумайте об использовании DBD::CSV.

. Затем вы можете открыть дескриптор базы данных в вашем файле CSV.выберите нужные столбцы с помощью запроса SELECT и запишите результаты с помощью Text::CSV или Text::CSV_XS.

Для получения дополнительной информации см. документацию DBD :: CSV или, например, этот простой скрипт-обертка для запроса файлов CSV .

0 голосов
/ 04 октября 2018

Фактический пример использования Text :: AutoCSV для удаления заданных именованных столбцов из произвольных файлов CSV, как в опубликованном вами коде (более сложный, чем примеры в документации только для записи определенных столбцов):

#!/usr/bin/perl
use warnings;
use strict;
use Text::AutoCSV qw/remove_accents/;

sub remove_columns {
  my ($infile, $outfile, $drop) = @_;
  my $csv = Text::AutoCSV->new(in_file => $infile, out_file => $outfile);
  # Normalize column names the same way that Text::AutoCSV does
  my %drops = map { my $h = remove_accents $_;
                    $h =~ s/[^[:alnum:]_]//gi;
                    $h = uc $h;
                    $h => 1 } @$drop;
  my @cols = grep { not exists $drops{$_} } $csv->get_fields_names;
  # Hack to avoid reading the file twice.
  $csv->{out_fields} = \@cols;
  $csv->write();
}

remove_columns "in.csv", "out.csv", [ "user", "timestamp" ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...