La programmation est tellement nouvelle pour moi que je m'excuse de ne pas savoir comment souligner la question.
J'ai un script PERL qui obtient une variable d'un outil interne. Ce n'est pas toujours à quoi cela ressemble, mais il suivra toujours ce modèle: p> avec Perl, quel est le moyen le plus simple d'obtenir chacune de ces lignes dans une variable lui-même? Selon ce que l'outil interne crache chaque ligne sera toujours différent et il peut y avoir plus de cinq lignes. La lettre capitalisée de chaque ligne est ce qu'elle finira par être triée par (tout comme tous les CS, tous les ES, etc.). Devrais-je regarder des expressions régulières? p> p>
5 Réponses :
use strict;
use warnings;
# this puts each line in the array @lines
my @lines = <DATA>; # <DATA> is a special filehandle that treats
# everything after __END__ as if it was a file
# It's handy for testing things
# Iterate over the array of lines and for each iteration
# put that line into the variable $line
foreach my $line (@lines) {
# Use split to 'split' each $line with the regular expression /s+/
# /s+/ means match one or more white spaces.
# the 4 means that all whitespaces after the 4:th will be ignored
# as a separator and be included in $col4
my ($col1, $col2, $col3, $col4) = split(/\s+/, $line, 4);
# here you can do whatever you need to with the data
# in the columns. I just print them out
print "$col1, $col2, $col3, $col4 \n";
}
__END__
darren.local 1987 A Sentece1
darren.local 1996 C Sentece2
darren.local 1991 E Sentece3
darren.local 1954 G Sentece4
darren.local 1998 H Sentece5
Pour chaque ligne de texte quelque chose comme ceci:
my ($domain, $year, $grade, @text) = split /\s+/, $line;
Si vous allez utiliser STRAT dans ce cas, utilisez le troisième argument pour limiter le nombre d'éléments qu'il revient. Si cette dernière colonne a une importepace importante, vous perdrez une partie des données.
En supposant que le texte soit mis dans une seule variable $ Info, vous pouvez alors la diviser en lignes distinctes à l'aide de la fonction Split Perl intrinsèque: où @Lines est un tableau de votre lignes. Le "\ n" est la regex pour une nouvelle ligne. Vous pouvez faire boucler chaque ligne comme suit: p> Vous pouvez ensuite diviser chaque ligne sur WhitSpace (regex \ s +, où le \ S est un caractère blanche et le moyen + 1 fois ou plus): p> et vous pouvez alors accéder à chaque champ directement via son index de tableau: $ champ [0], $ champ [1], etc. p > ou, vous pouvez faire: p> qui mettra les champs dans chaque ligne en variables nommées séparées. P> maintenant - si vous voulez Pour Trier B> Vos lignes par le caractère de la troisième colonne, vous pouvez le faire: P> my %hash = (); # declare new hash
foreach $line (@arr) { # loop through lines
my @fields = @$line; # deference the field array
my $el = $fields[2]; # get our key - the character in the third column
my $val = "";
if (exists $hash { $el }) { # check if key already in hash
my $val = $hash{ $el }; # get the current value for key
$val = $val . "\n" . $line; # append new line to hash value
} else {
$val = $line;
}
$hash{ $el } = $val; # put the new value (back) into the hash
}
Si vous allez utiliser STRAT dans ce cas, utilisez le troisième argument pour limiter le nombre d'éléments qu'il revient. Si cette dernière colonne a une importepace importante, vous perdrez une partie des données.
Merci Richard - chaque ligne doit être regroupée par les lettres capitalisées. Selon la sortie de cette requête, je pourrais avoir jusqu'à 20 lignes ou aussi peu que 2 lignes. Les lignes avec "C" doivent entrer dans une variable, des lignes avec "B" doivent entrer dans leur propre variable, etc. cela fonctionnera-t-il?
En utilisant la fonction de tri dans ma réponse ci-dessus, votre tableau sera trié alphanumériquement. Donc, "un" S apparaîtra d'abord "B" suivant et ainsi de suite. Si vous souhaitez mettre toutes les lignes «a» dans une seule variable, il existe (comme tout problème de programmation) un certain nombre de possibilités. Vous pouvez utiliser un hash / map à clé, avec les caractères "A", etc. comme clé, avec la valeur étant a) une gamme de lignes ou b) un seul simple à lequel vous appuyez sur les lignes ultérieures que vous les trouvez. Voir ici a "rel =" Nofollow Noreferrer "> cs.mcgill.ca/~abatko/computers/programme/programming/perl/howto/ hachage / ... > Pour un tutoriel sur l'utilisation de hachages.
Mon lien a été brouillé - c'est cs.mcgill.ca/ ~ Abatko / Ordinateurs / Programmation / Perl / Howto / Hash
Modifier: Je voulais dire b) une seule chaîne à laquelle vous pouvez ajouter ... (Je n'ai pas encore travaillé sur la manière de modifier des commentaires)
@scraft: J'ai ajouté un exemple sur la façon d'utiliser un hachage.
@Richard: Vous ne modifiez pas les commentaires (qui craint), mais vous pouvez les supprimer et ré-commenter comme je le fais. :)
J'aime utiliser Déballez pour ce genre de chose. C'est rapide, flexible et réversible.
Vous devez juste avoir besoin de connaître les positions de chaque colonne, et Si vous changez quelque chose dans l'une des colonnes, il est facile de revenir au format d'origine en reconditionnement avec le même format: P> Débattre code> peut automatiquement couper l'espacement supplémentaire de chaque colonne. P> my $lines = '...multiline string...';
open my($fh), '<', \ $lines;
while( <$fh> ) {
... same as before ...
}
Un bel exemple de perl lisible ... (même à un utilisateur une fois à deux ans)
Je ne suis pas sûr du format que vous avez vu parce que j'ai commis une erreur dans le premier que j'ai posté, mais nous nous sommes retrouvés au même format.
-1: Oui, c'est rapide, mais c'est aussi beaucoup plus à coder que lorsque vous utilisez Split, donc plus d'effort et plus d'erreurs. Sauf s'il ya vraiment beaucoup de données à extraire, cela ressemble à une optimisation prématurée pour moi.
Adrian, je suis désolé d'être contrarié que je n'aime pas votre réponse, mais que vous auriez du mal à expliquer comment un seul appel à décompresser est beaucoup plus de code qu'un seul appel à scinder. Le déballer est beaucoup plus flexible. J'appelle des raisins acides ici.
S'il vous plaît, ne tournons pas cela en quelque chose de personnel. Regardez la réponse de Nifle, il est évident que son approche prend beaucoup moins de code que le vôtre, même après la modification qu'il a faite pour réparer le bug que vous avez repéré.
+1 Bonne illustration de Déballez code>, un outil fréquemment négligé. Détail très mineur: Si une réversibilité parfaite est nécessaire, vous souhaitez utiliser a * code> plutôt que a * code>. Ce dernier éliminera les espaces de fuite, ce qui pourrait être indésirable (par exemple, si les phrases diffèrent de longueur, mais les utilisateurs des données ne veulent pas des enregistrements déchiquetés sur le voyage inversé).
@Fm: A * est probablement mieux. C'est la raison pour laquelle le format est dans une variable: vous le modifiez un endroit où vous voulez faire quelque chose de différent.
Puis-je l'avoir expliqué dans des termes de la personne stupide que cette ligne fait?: Mon format $ = 'A23 A8 A7 A *';
@ Scraft3613: C'est la chaîne de format Pack. Il n'y a pas de magie dans cette ligne. Voir la documentation du pack, que je suis liée à la réponse.
De retour dans les états, je n'ai jamais besoin de décompresser FN puisque TOUS DEV sont suffisamment considérables pour ajouter des délimiteurs. Merci @briandfoy
Utilisez cpan et mon module Dataextract :: fixeWidth :
#!/usr/bin/env perl
use strict;
use warnings;
use DataExtract::FixedWidth;
my @rows = <DATA>;
my $defw = DataExtract::FixedWidth->new({ heuristic => \@rows, header_row => undef });
use Data::Dumper;
print Dumper $defw->parse( $_ ) for @rows;
__DATA__
darren.local 1987 A Sentence1
darren.local 1996 C Sentence2
darren.local 1991 E Sentence3
darren.local 1954 G Sentence4
darren.local 1998 H Sentence5
Où sont ces données / lignes? Votre outil interne les a-t-il mis dans une seule variable? Ou ce texte est-il dans un fichier à lire?
L'outil les met en une seule variable.
+1 pour Perl Newbie - Le phraseX signifie-t-il qu'il existe une phrase multimôlée à la fin de chaque ligne? Gardez à l'esprit qu'une phrase serait également scindée par \ S +