2010-05-01 10 views
1

J'ai un fichier SQL qui me donnera une sortie comme ci-dessous:Comment utiliser Perl pour analyser la sortie de la commande sqlplus?

10|1 
10|2 
10|3 
11|2 
11|4 
. 
. 
. 

J'utilise dans un script Perl comme ci-dessous:

my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`; 

après cette déclaration ci-dessus, puisque @tmp_cycledef a tous la sortie de la requête SQL, je veux montrer la sortie comme:

10 1,2,3 
11 2,4 

Comment pourrais-je faire cela en utilisant Perl?

EDIT:

J'utilise le code suivant:

foreach my $row (@tmp_cycledef) 
{ 
     chomp $row; 
     my ($cycle_code,$cycle_month)= split /\s*\|\s*/, $row; 
     print "$cycle_code, $cycle_month\n"; 
     $hash{$cycle_code}{$cycle_month}=1 
} 

foreach my $num (sort keys %hash) 
{ 
     my $h = $hash{$num}; 
     print join(',',sort keys %$h),"\n"; 
} 

les impressions des états d'impression poing:

 2, 1 
    2, 10 
    2, 11 
    2, 12 
    3, 1 
    3, 10 
    3, 11 

mais en est toujours

1,10,11,12 
1,10,11,12 
1,10,11,12 
1,10,11,12 
1,10,11,12 
1,10,11,12 
1,10,11,12 

Répondre

1

Eh bien, celui-ci est en fait comment vous pouvez le faire en perl:

# two must-have pragmas for perl development 
use strict;  
use warnings; 

Perl permet les variables à créer au fur et à mesure de leur utilisation, $feldman = some_function() signifie que vous avez maintenant la variable $feldman dans votre espace de noms local. Mais la mauvaise partie à ce sujet est que vous pouvez taper $fldman et prendre beaucoup de temps à découvrir pourquoi ce que vous pensiez était $feldman n'a aucune valeur. L'activation de strictures signifie que votre code ne peut pas être compilé s'il rencontre une variable non déclarée. Vous déclarez une variable avec un my ou our déclaration (ou ancien code Perl une déclaration use vars.

Activation warnings juste vous avertit lorsque vous n'obtenez pas les valeurs que vous attendez. Souvent, les avertissements ont tendance à être trop chatouilleux, mais ils sont généralement une bonne chose à développer code avec.

my %hash; # the base object for the data 

ici, j'ai déclaré une variable de hachage que j'ai appelé créative %hash. Le Sigil (prononcé « Sijil ») « % » indique que est une carte de paires nom-valeur.instruction déclaré la variable et le rend légal pour le compilateur. Le compilateur m'avertira de toute utilisation de %hsh.

L'élément suivant est une boucle foreach (qui peut être abrégée "pour"). La boucle va traiter la liste des lignes @tmp_cycledef en attribuant chacune à tour de rôle à $row. (mon$row).

  1. Nous chomp première ligne, en supprimant le caractère de fin de ligne pour cette plate-forme.
  2. Nous split la ligne sur le « | » caractère, créant une liste de chaînes qui ont été séparées par un tuyau.
  3. Et puis nous le stockons dans un hachage à deux couches. Puisque nous voulons les regrouper par au moins le premier nombre. Nous pourrions le faire en tableau, et créer un tableau à l'emplacement dans le hachage comme ceci: push @{$hash{$key}}, $val, mais je veux généralement à l'effondrement des doublons

Ici (pas qu'il y avait des doublons dans votre échantillon.):

foreach my $row (@tmp_cycledef) { 
    chomp $row; # removes the end-of-line character when present. 
    my ($key, $val) = split /\|/, $row; 
    # One of the best ways to merge lists is a presence-of idea 
    # with the hash holding whether the value is present 
    $hash{$key}{$val} = 1; 
} 

Une fois que nous avons les données dans la structure, nous devons itérer les deux niveaux de hachage keys. Vous vouliez séparer les nombres "de premier niveau" par des lignes, mais vous vouliez que les deuxièmes nombres soient concaténés sur la même ligne. Nous imprimons donc une ligne pour chacun des premiers chiffres et join la liste des chaînes stockées pour chaque numéro sur la même ligne, délimitée par des virgules. Nous aussi sortez la liste: { $a <=> $b } prend juste aux clés et numériquement les compare. Donc, vous obtenez un ordre numérique.

# If they were alpha keys our sort routine, we would just likely say sort keys %hash 
foreach my $num (sort { $a <=> $b } keys %hash) { 
    my $h = $hash{$num}; 
    print "$num ", join(',', sort { $a <=> $b } keys %$h), "\n"; 
} 

Comme je l'ai dit dans les commentaires, sort, par défaut, trie dans l'ordre des caractères afin que vous puissiez simplement dire sort keys %hash.

Pour vous aider, vous avez vraiment besoin de lire certains d'entre eux:

+0

Merci ... comme je suis nouveau à perl .could vous expliquer moi s'il vous plaît comment cela fonctionne? – Vijay

+0

++, j'étais trop paresseux pour écrire le vrai code Perl :-) –

+0

@benjamin bouton: Je l'ai rempli un peu. – Axeman

1

Utilisation un hash of arrays pour recueillir toutes les valeurs d'une clé unique ensemble, puis les imprimer:

init hash 
for each line: 
    parse into key|value 
    append value to hash[key] 

for each key in hash: # you can sort it, if needed 
    print out key, list of values 
0

Si votre entrée est triée (comme dans l'échantillon fourni), vous ne devez pas vraiment à se soucier de la valeur de hachage des tableaux/hash. Le code est un peu plus, mais ne vous oblige pas à comprendre les références et devrait courir plus vite pour les grands ensembles de données:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @tmp_cycledef = <DATA>; 

my $last_key; 
my @values; 
for (@tmp_cycledef) { 
    chomp; 
    my ($key, $val) = split '\|'; 

    # Seed $last_key with the first key value on the first pass 
    $last_key = $key unless defined $last_key; 

    # The key has changed, so it's time to print out the values associated 
    # with the previous key, then reset everything for the new one 
    if ($key != $last_key) { 
    print "$last_key " . join(',', @values) . "\n"; 
    $last_key = $key; 
    @values =(); 
    } 

    # Add the current value to the list of values for this key 
    push @values, $val; 
} 

# Don't forget to print out the final key when you're done! 
print "$last_key " . join(',', @values) . "\n"; 

__DATA__ 
10|1 
10|2 
10|3 
11|2 
11|4 
Questions connexes