Ils n'ont manifestement pas un espacement égal entre chaque élément de la ligne, mais ils sont alignés sur la base des colonnes. Je baguette pour éditer le 3e élément de R3 de XA à XAHBB mais impossible de maintenir l'alignement des colonnes
R1 X XA 0i 1i H 0i R2 X XA 1i 1i H 0i R3 X XAHBB 1i 1i H 0i R4 X XA 1i 1i H 0i R5 X XA 1i 1i H 0i R6 X XA 0i 0i X 0i
Ma sortie actuelle est comme indiqué ci-dessous
R1 X XA 0i 1i H 0i R2 X XA 1i 1i H 0i R3 X XAHBB 1i 1i H 0i R4 X XA 1i 1i H 0i R5 X XA 1i 1i H 0i R6 X XA 0i 0i X 0i
Où, comme mon résultat attendu devrait ressemblez à ceci ci-dessous
my $cur_line_num = 1;
while(<Sourcefile>){
my @RowEdit = split (" ",$_);
if($RowEdit[0]=~ m/^R3$/s){
$RowEdit[2]="RowEdit[2]HBB"
}
my $curr_line = join(" ", @RowEdit)
print $newfile "curr_line\n";
$cur_line_num++;
}
print "$cur_line_num\n";
Comment maintenir l'alignement des colonnes lors de l'édition d'un fichier?
3 Réponses :
C'est à cela que sert Text :: Table :
#!/usr/bin/perl
use warnings;
use strict;
use Text::Table;
my $table = 'Text::Table'->new;
while (<DATA>) {
my @RowEdit = split ' ';
if ($RowEdit[0] eq 'R3') {
$RowEdit[2] .= 'HBB';
}
$table->add(@RowEdit);
}
print $table;
print $. + 1, "\n";
__DATA__
R1 X XA 0i 1i H 0i
R2 X XA 1i 1i H 0i
R3 X XA 1i 1i H 0i
R4 X XA 1i 1i H 0i
R5 X XA 1i 1i H 0i
R6 X XA 0i 0i X 0i
Notez également tous les autres petits changements que j'ai faits:
$. . / s change le comportement de . dans une regex. Cela n'a aucun sens de l'utiliser dans une regex qui ne contient pas de point. De plus, eq peut être utilisé pour l'équialité des chaînes s'il n'y a qu'une seule chaîne qui correspond à l'expression régulière - elle est plus facile à lire et plus rapide à exécuter. $ _ comme deuxième argument si aucun n'est fourni. Taper $ _ n'importe où en dehors de grep ou de map est une odeur de code - soit c'est quelque chose qui vaut un nom, ou peut être écrit sans. li>
. = . y a-t-il un moyen de le faire sans utiliser l'extension Text :: Table? avec des commandes perl basiques
Vous pouvez toujours lire le code source de Text :: Table - il suffit de cliquer sur Source .
sprintf et format vous donnent quelque chose de similaire, mais ils ne sont pas de nature dynamique. Vous devrez choisir vos largeurs de colonne à l'avance (bien que vous puissiez peut-être `` détecter '' quelle serait la cellule la plus large d'une colonne et l'utiliser)
J'imprime ces données d'un fichier vers une autre solution de sprintf fonctionnera avec ce scénario @Sobrique
Vous pouvez le faire avec printf () . Mais vous devez faire deux passes sur les données (car il n'y a aucun moyen de savoir quelle est la largeur de colonne la plus large avant d'avoir vu chaque enregistrement de données).
Quelque chose comme ça semble faire l'affaire.
R1 X XA 0i 1i H 0i R2 X XA 1i 1i H 0i R3 X XAHBB 1i 1i H 0i R4 X XA 1i 1i H 0i R5 X XA 1i 1i H 0i R6 X XA 0i 0i X 0i
Le résultat est:
#!/usr/bin/perl
use strict;
use warnings;
my @widths; # Store the max widths for each column
my @data; # Store the actual data
while (<DATA>) {
my @row;
# Use the first line to initialise the @widths array
if ($. == 1) {
@row = /(\S+\s*)/g;
@widths = map { length() - 1} @row; # Subtract 1 for gutter
@row = map { s/\s+$//; $_ } @row; # Remove trailing whitespace
} else {
@row = split;
}
# Split the data
my @row = split;
# Store the split data
push @data, \@row;
# Make the (optional) transformation
$row[2] .= 'HBB' if $row[0] eq 'R3';
# Look at each column in this row of data and
# compare it to the widest data that we've previously
# seen in that column.
for my $i (0 .. $#row) {
$widths[$i] = length $row[$i]
if length $row[$i] > ($widths[$i] // 0);
}
}
# Create a printf output format using the column
# widths we've stored in @widths
my $fmt = join ' ', map { "%-${_}s" } @widths;
# Use printf to display each line of data.
printf "$fmt\n", @$_ for @data;
__DATA__
R1 X XA 0i 1i H 0i
R2 X XA 1i 1i H 0i
R3 X XA 1i 1i H 0i
R4 X XA 1i 1i H 0i
R5 X XA 1i 1i H 0i
R6 X XA 0i 0i X 0i
Mais je pense que la solution Text :: Table est meilleure :-)
Comme il s'agit de l'une des tâches pour lesquelles Perl a été initialement écrit ( Practical Extraction and Reporting Language a >), alors pour être complet, il faut également mentionner les bons vieux formats Perl simples, voir man perlform . Par exemple, format STDOUT =
@<<<<< @ @<<<<, ....
$col1, $col2, $col3, ...
.
for my ... (...) {
# set $col1 .... and then
write
}