J'ai une entrée du format suivant:
Je suis capable d'extraire facilement ces champs d'individus à l'aide du regex J'aimerais que la sortie ressemble à ceci. Veuillez noter que je devais utiliser des points pour aligner le dernier champ car je n'ai pas pu utiliser la barre d'espace pour le faire, je ne sais pas pourquoi. Anyhoo. P> J'ai pensé à mettre le nom / (\ s +) \ s + (\ s +) \ s + (\ s +) \ s + / code>. Je les ai nommés
$ temps code>,
$ nom code> et
$ numéro code>. Mon problème est que je veux afficher cela afin que le numéro
$ code> aligne parfaitement. Parce que le nom
$ code> peut être de n'importe quelle longueur, quelle est la meilleure solution pour cela? P>
$ code> dans un tableau. Puis utilisez une fonction pour trouver celui avec le nombre de caractères le plus long. Enfin, je renverrais le nom plus court pour correspondre au nom le plus long. Y a-t-il un moyen meilleur et plus efficace de faire cela? P> p>
6 Réponses :
Il a été donné par quelqu'un ici : Vous pouvez modifier des noms de variables et fonctionner pour vous. P> P>
Pour formater, essayez d'utiliser le Sprintf fonction, comme dans
$line = sprintf "%-12s %-20s %-s\n", $time, $name, $number;
Ce que vous faites, vous allez avoir à faire avec deux passes - une pour trouver la longueur, une à imprimer, en utilisant cette longueur dans le formatage. J'irais avec la réponse Sprintf déjà donnée pour le formatage, personnellement, juste la variation du numéro dedans. P>
exactement comment vous effectuez les deux passes dépend plutôt de l'endroit où les données proviennent de - lire un fichier deux fois plus sage que le prétraitement de la prétraitement de la mémoire si le fichier est énorme, mais la solution de tableau que vous proposez des sons pour moi . p>
Si vous ne connaissez pas la largeur maximale du champ central, vous devrez faire deux passes sur les données comme @ ijw note .
#!/usr/bin/perl use strict; use warnings; use Fcntl qw( :seek ); my $max_length = 0; my $data_pos = tell DATA; while ( my $line = <DATA> ) { last unless $line =~ /\S/; my $name = (split ' ', $line)[1]; my $name_length = length $name; $max_length = $name_length if $name_length > $max_length; } seek DATA, $data_pos, SEEK_SET; while ( my $line = <DATA> ) { last unless $line =~ /\S/; my ($date, $name, $ip) = split ' ', $line; printf "%s %-${max_length}s %s\n", $date, $name, $ip; } __DATA__ 09:08:11 XXXXXXXXXXXXX 1.1.1.1 09:09:03 YYYYYYYY 2.2.2.2 09:12:37 ZZZZ 3.3.3.3
regarder Perl6 :: Formulaire .
Ceci est L'approche recommandée en utilisant format . Voir cette réponse de pile précédente Réponse: quelles autres langues ont des fonctionnalités et / ou des bibliothèques similaires au format de Perl? em> p> Voici un exemple de perl6 :: Formulaire faire exactement ce que vous voulez avec Vos données: p> nb. Si vos champs de données deviennent plus grands que les champs de formulaire spécifiés, vous rencontrez des problèmes de formatage (et la même chose s'applique également aux solutions Sprintf et format). P> Il est facile de corriger en fonction de vos besoins de sortie. . Par exemple, si vous souhaitez maintenir la stabilité tabulaire, alors ... p> ... Word word envelopper chaque colonne pour vous. P> p>
p>
$lineLength = length($line1); write; } close FD1; format STDOUT = @>>>>> @* $lineLength,$line1 . ; So, in above example, "$lineLength" is pushed to the right with leading spaces.
Utilisez l'option de mise en forme du code pour spécifier que la police et la préformatage de la largeur fixe doivent être utilisées. :)
Je faisais juste cette édition sur mon téléphone jusqu'à ce que je réalisais que c'était trop difficile.
Les chiffres sont-ils toujours à un chiffre chacun? Sinon, que veux-tu faire?
Merci pour la modification. Bon à savoir que je peux ajouter les espaces dans l'option de code.