J'ai un fichier journal ASCII avec du contenu que j'aimerais extraire. Je n'ai jamais pris le temps d'apprendre Perl correctement, mais je pense que c'est un bon outil pour cette tâche.
Le fichier est structuré comme celui-ci: p>
... ... some garbage ... ... garbage START what i want is on different lines END ... ... more garbage ... next one START more stuff I want, again spread through multiple lines END ... more garbage
6 Réponses :
Comment puis-je saisir plusieurs lignes après une ligne correspondante à Perl? P>
Comment est-ce celui-là? Dans celui-ci, la chaîne d'extrémité est $ ^, vous pouvez le changer à votre chaîne de fin. P>
Je suis aussi novice, mais les solutions offrent de nombreuses méthodes ... laissez-moi savoir plus spécifiquement ce que vous voulez que cela diffère du lien ci-dessus. P>
Vous voulez que l'opérateur de flip-flop (également appelé l'opérateur de plage) remplace l'appel à .. code>
Imprimer code> Avec tout ce que vous voulez réellement faire (par exemple, appuyez sur la ligne dans un tableau, éditer-le, formatez-le, peu importe). Je suis
Suivant code> -ing -ing passé les lignes qui ont réellement
Démarrer code> ou
fin code>, mais vous ne voulez peut-être pas que ce comportement. Voir Cet article pour une discussion de cet opérateur et Autres variables spéciales perl utiles. P> p>
Travaille pour moi!! Étant donné que je veux exclure les lignes avec les délimiteurs, je peux pipeler la sortie via Grep -V par exemple. BTW, en première ligne après le début, comment pourrais-je supprimer le premier personnage d'une ligne?
La version one-liner: Perl -ne 'Imprimer si / /start/../end/'
William, qui imprimera les lignes avec début et fin. Si vous ne le souhaitez pas, voici l'ONLINAINE DE TELEMACHUS: PERL -NE 'IF (/START/../end/) {IMPRIMER SAUF / START / OR / FIN /}' '
@Telemachus - Comment puis-je obtenir ceci pour travailler avec une variable plutôt que de lire un fichier. Dis que j'ai un $ variable = "Ne voulez pas que cette partie commence, je veux cette partie à la place finale"; code>? Parce que j'ai du mal à obtenir le même effet lorsqu'il s'agit d'une variable par opposition à un fichier, votre aide est très appréciée, merci
@ Perl-utilisateur si la chaîne est plus longue (et surtout si elle est séparée par des lignes neuves ou quelque chose de très régulier), vous pouvez utiliser ouvrir code> et traiter une variable de chaîne comme un fichier de fichiers. Mais si la corde ressemble vraiment à ce que vous avez ici, cela ne semble pas la peine. Vous pouvez simplement utiliser la substitution pour supprimer les pièces que vous ne voulez pas:
s /^.* start // code> puis
s / fin $ // code>, par exemple. Si c'est plus complexe, j'ouvre une nouvelle question.
while (<>) { chomp; # strip record separator if(/END/) { $f=0;} if (/START/) { s/.*START//g; $f=1; } print $_ ."\n" if $f; } try to write some code next time round
Je comprends et j'aurais écrit du code si j'avais déjà commencé à apprendre Perl. J'ai réussi à passer avec Awk et Sed jusqu'à présent. Mais de toute façon, merci pour votre conseil.
Après la réponse de Telemachus, les choses ont commencé à verser. Cela fonctionne comme la solution que je regarde après tout.
Cela fonctionne pour moi, bien que le code puisse être classé comme laid; C'est parce que je suis actuellement un nouveau venu à Perl. Quoi qu'il en soit, voici: p> J'espère que cela profite également aux autres.
Bravo. P> p>
de Réponse de Perlfaq6 à Comment puis-je extraire des lignes entre deux motifs qui sont eux-mêmes sur différentes lignes?
Vous pouvez utiliser un opérateur quelque peu exotique de Perl. (documenté dans Perlop): p> Si vous vouliez du texte et non des lignes, vous utiliseriez P> while (<>) {
$in_header = 1 .. /^$/;
$in_body = /^$/ .. eof;
# now choose between them
} continue {
$. = 0 if eof; # fix $.
}
Pas trop mal pour venir d'un "nouveau-livrer virtuel". Une chose que vous pourriez faire est de mettre le "$ trouvée = 1" à l'intérieur du "if ($ trouvés == 0)" de sorte que vous ne faites pas cette affectation à chaque fois entre $ départ et $ STOP.
Une autre chose qui est un peu laide, à mon avis, est que vous ouvrez le même fichierHandler chaque fois que vous entrez dans le bloc $ start / $ $. P>
Ceci montre un moyen de contourner cela: P >
#!/usr/bin/perl use strict; use warnings; my $start='CINFILE=$'; my $stop='^#$'; my $filename; my $output; my $counter=1; my $found=0; while (<>) { # Find block of lines to extract if( /$start/../$stop/ ) { # Start of block if( /$start/ ) { $filename=sprintf("boletim_%06d.log",$counter); open($output,'>>'.$filename) or die $!; } # End of block elsif ( /$end/ ) { close($output); $counter++; $found = 0; } # Middle of block else{ if($found == 0) { print $output (split(/ /))[1]; $found=1; } else { print $output $_; } } } # Find block of lines to extract }
Merci. Je pense maintenant que je devrais perdre du temps pour apprendre correctement Perl. Mon arrière-plan est sur C, certains C ++ et certains Fortran, de sorte qu'il semble familier.
BTW, j'avoue que j'étais laxiste sur l'ouverture de nombreux dossiers, ma principale préoccupation à l'époque consistait à obtenir quelque chose qui fonctionnait, même pas trop bien.
Utilisez le match global / g plutôt que de le laisser arrêter au terminal de ligne.
Vous vouliez dire / s? Afaik / g est Match multiple B>.
Ceci est une question en double. Voir .... stackoverflow.com/questions/296366/...
Voir aussi Comment Lignes d'impression entre deux modèles, inclus ou exclusive