2010-10-16 27 views
2

chat monday.csvComment obtenir le nom du fichier d'entrée dans un Perl One-Liner?

223,22; 1256,4
227,08; 1244,8
228,08; 1244,7
229,13; 1255,0
227,89; 1243,2
224,77; 1277,8

chat tuesday.csv

227,02; 1266,3
227,09; 1234,9
225,18; 1244,7
224,13; 1255,3
228,59; 1263,2
224,70; 1247,6

Ce Perl one-liner me donne la ligne avec la valeur la plus élevée dans la la seconde colonne des rangées où dans la première colonne les 3 premiers chiffres sont 227 ou 226 à partir du fichier « monday.csv »:

$ perl -F\; -ane '$hash{$_} = $F[1] if /22[78]/; END{ print and exit for sort{ $hash{$b} <=> $hash{$a} } keys %hash }' monday.csv

Ce Perl one-liner me donne la ligne avec la valeur la plus élevée dans la deuxième colonne des lignes où dans la première colonne les 3 premiers chiffres sont 227 ou 226 de tous les fichiers * day.csv:

$ perl -F\; -ane '$hash{$_} = $F[1] if /22[78]/; END{ print and exit for sort{ $hash{$b} <=> $hash{$a} } keys %hash }' *day.csv

Comment ne réécrire celui-liner pour obtenir un signal de sortie:

filename: « ligne avec la valeur la plus élevée dans la deuxième colonne à partir des lignes où dans la première colonne les 3 premiers chiffres sont 227 ou 226 à partir de le fichier 'filename.csv' "

pour chaque fichier *day.csv?

Répondre

5

Vous pouvez utiliser $ARGV pour le nom du fichier en cours. Si vous êtes seulement intéressé par le max, pas besoin de stocker toutes les valeurs et ensuite les trier; Au lieu de cela, il suffit de stocker le maximum pour chaque fichier. De plus, votre regex devrait probablement être ancrée au début de la ligne.

# Line breaks added for display purposes. 
perl -F\; -ane ' 
    $max{$ARGV} = $F[1] if /^22[78]/ and $F[1] > $max{$ARGV}; 
    END{ print "$_\t$max{$_}" for sort keys %max} 
' *day.csv 

Ou, si vous voulez stocker toute la ligne où le max se produit:

perl -F\; -ane ' 
    ($max{$ARGV}{ln}, $max{$ARGV}{mx}) = ($_, $F[1]) 
     if /^22[78]/ and $F[1] > $max{$ARGV}{mx}; 
    END{ print "$_\t$max{$_}{ln}" for sort keys %max} 
' *day.csv 
2

Le nom de fichier est contenu dans la variable $ARGV:

$ ARGV

contient le nom du fichier en cours lors de la lecture de <>.


Cependant, les one-liners présentés ont un problème; Et si vous avez des valeurs répétées de votre première colonne?

Un meilleur-liner serait:

$ perl -F/;/ -MList::Util=max -lane 'push @{ $wanted{$ARGV} }, $F[1] if $F[0] =~ /22[78]/; } END { print "$ARGV : ", max(@{ $wanted{$_} }) for keys %wanted;' *.csv 

Basé sur le commentaire:

$ perl -F/;/ -lane '$wanted{$ARGV} = \@F if $F[1] >= $wanted->{$ARGV}[1] && $F[0] =~ /22[78]/; } END { print "$_ : @$wanted{$_}" for keys %wanted;' *.csv 
+0

Je ne vois pas le problème avec des valeurs répétées. –

+0

dans la première colonne. Mais je vois un problème avec des valeurs répétées dans la deuxième colonne. La raison est, il a oublié de mentionner, que je voudrais avoir la dernière valeur dans le fichier des valeurs les plus élevées s'il y a plus d'une valeur plus élevée par fichier. –

+0

Mais je pense qu'il y a beaucoup d'erreurs dans votre deuxième one-liner. –

0

Si je voudrais toute la ligne, je pouvais le faire (en fonction de la réponse FM):

perl -F\; -ane '$max{$ARGV} = $_ if /^22[78]/ and $F[1] >= (split /;/, $max{$ARGV})[1]; END{ print "$_\t$max{$_}" for sort keys %max}' *day.csv 

J'ai trouvé une solution plus courte.
tous les fichiers:

perl -F\; -anE '$max{$ARGV} = [@F] if /^22[78]/ and $F[1] >= $max{$ARGV}->[1]; END{ print "$_\[email protected]{$max{$_}}" for sort keys %max}' *day.csv 

un fichier:

perl -F\; -anE '$max = [@F] if /^22[78]/ and $F[1] >= $max->[1]; END{ print "@$max" }' monday.csv 

ou s'il n'y a pas beaucoup d'espace disponible

perl -F\; -anE'$m{$ARGV}=[@F]if/^22[78]/&&$F[1]>=$$m{$ARGV}[1]}print"$_\[email protected]{$m{$_}}"for sort keys%m;{' *day.csv 

perl -F\; -anE'$m=[@F]if/^22[78]/&&$F[1]>=$$m[1]}print"@$m";{' monday.csv 

Comme Zaid a révélé: pour obtenir la dernière ligne avec la valeur la plus élevée en cas de répétition des valeurs les plus élevées dans un fichier j'ai changé la partie "$ F [1]> $ max ..." - en "$ F [1]> = $ max".