2011-01-03 4 views
2

J'ai un ensemble de données délimité par des tabulations avec les chaînes d'agents utilisateur entre guillemets. J'ai besoin d'analyser chacune de ces colonnes et basé sur la réponse de mon other post j'ai utilisé le module Text :: CSV.Analyse du fichier délimité par des tabulations avec des guillemets doubles en Perl

94410634 0 GET "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; AskTB5.5)" 1 

Le code est un code simple.

#!/usr/bin/perl 

use strict; 
use warnings; 
use Text::CSV; 

my $csv = Text::CSV->new(sep_char => "\t"); 

    while (<>) { 
     if ($csv->parse($_)) { 
      my @columns = $csv->fields(); 
      print "@columns\n"; 
     } else { 
      my $err = $csv->error_input; 
      print "Failed to parse line: $err"; 
     } 
    } 

mais je reçois l'erreur Failed to parse line: quand je l'essayer sur cet ensemble de données. Qu'est-ce que je fais mal? J'ai besoin d'extraire la 4ème colonne contenant les chaînes d'agent utilisateur pour un traitement ultérieur.

+0

êtes-vous sûr que ce sont des onglets, pas d'espaces? En utilisant * '' * comme sep_char comme ceci * mon $ csv = Text :: CSV-> nouveau ({sep_char => ''}); * (notez aussi les {} s autour des options) fonctionne (bien qu'il fasse l'useragent champ le 8ème champ). – MkV

+0

@MKV - Je suis sûr que le formatage SO supprimé les onglets - dans ma réponse, j'ai explicitement re-construit la chaîne à séparer par des tabulations pour cette raison – DVK

+0

@DVK Spaces expliquerait cependant l'erreur OP. – marcog

Répondre

6
  1. Vos arguments du constructeur doivent être dans un hashref, pas un hachage:

    mon csv $ = Text :: CSV> new ({sep_char => "\ t"}); Etes-vous sûr que l'ensemble de données est exactement ce que vous pensez qu'il est? Peut-être qu'il y a une double citation manquant quelque part ou il n'y avait pas d'onglets?

    Pour vérifier le contenu du fichier, êtes-vous sous Unix/Linux ou Windows? Sous Unix, veuillez exécuter ceci: cat -vet my_log_file_name | head -3 et vérifiez si la sortie comporte des espaces ou des séquences "^ I" où vous attendez des onglets. cat -vet imprime tous les caractères spéciaux comme des séquences spéciales imprimables (TAB =>^I, saut de ligne =>$, etc ...)

Le test suivant fonctionne parfaitement sur mon ActivePerl:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Text::CSV; 

my $s = qq[94410634\t0\tGET\t"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; AskTB5.5)"\t1\n];; 
my $csv = Text::CSV->new({sep_char => "\t"}); 

if ($csv->parse($s)) { 
    my @columns = $csv->fields(); 
    print "c=$columns[3]\n"; 
} else { 
    my $err = $csv->error_input; 
    print "Failed to parse line: $err"; 
} 

sortie:

C:\> perl d:\scripts\test4.pl 
c=Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.6; ... 
+0

Eish, le point 1 signifie mon [+17 réponse] (http: // stackoverflow .com/questions/4500407/in-perl-how-can-i-correctement-parse-tab-space-délimité-files-with-quoted-string/4500478 # 4500478) a une erreur. Je ferais mieux de réparer ça! – marcog

+0

Le problème peut être avec le module Text :: CSV installé sur le serveur. Je vérifie aussi cela parce que j'ai toujours l'erreur. Il est temps de voir l'administrateur du système, je suppose :). – sfactor

+0

@marcog - super - et les 17 upvoters et 17 + N téléspectateurs (moi inclus) n'a pas remarqué. Tant pis pour le fameux collectif SO sagesse :) – DVK

Questions connexes