12
votes

Comment "pad" une chaîne de longueur variable pour avoir une colonne dernière alignée

J'ai une entrée du format suivant:


xxx

Je suis capable d'extraire facilement ces champs d'individus à l'aide du regex / (\ s +) \ s + (\ s +) \ s + (\ s +) \ s + / . Je les ai nommés $ temps , $ nom et $ numéro . Mon problème est que je veux afficher cela afin que le numéro $ aligne parfaitement. Parce que le nom $ peut être de n'importe quelle longueur, quelle est la meilleure solution pour cela?

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.


xxx

J'ai pensé à mettre le nom $ 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?


4 commentaires

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.


6 Réponses :


5
votes

Il a été donné par quelqu'un ici : xxx

Vous pouvez modifier des noms de variables et fonctionner pour vous.


0 commentaires

22
votes

Pour formater, essayez d'utiliser le Sprintf fonction, comme dans

$line = sprintf "%-12s %-20s %-s\n", $time, $name, $number;


0 commentaires

0
votes

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.

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 .


0 commentaires

2
votes

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


0 commentaires

3
votes

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?

Voici un exemple de perl6 :: Formulaire faire exactement ce que vous voulez avec Vos données: xxx


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).

Il est facile de corriger en fonction de vos besoins de sortie. . Par exemple, si vous souhaitez maintenir la stabilité tabulaire, alors ... xxx

... Word word envelopper chaque colonne pour vous.


0 commentaires

0
votes
      $lineLength = length($line1);
      write;
}
close FD1;

format STDOUT =
@>>>>> @*
$lineLength,$line1
.
;
So, in above example, "$lineLength" is pushed to the right with leading spaces.

0 commentaires