Je comprends comment utiliser la fonction printf de awk, mais je ne veux pas spécifier chaque champ.
Par exemple, supposons qu'il s'agit de mon fichier:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Je veux le formater pour que le premier champ de chaque enregistrement soit la largeur de c11 - la cellule la plus longue du premier champ:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Je comprends que je pourrais préciser:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Supposons que je sais ce que je veux que la largeur de la première colonne soit, mais je ne sais PAS combien de champs sont dans le fichier. Fondamentalement, je veux faire quelque chose comme:
... '{printf "%-3s|", $1}'
... puis imprimez le reste des champs dans leur format d'origine.
awk
text-formatting
printf
Kayli O'Keefe
la source
la source
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(ici en ajoutant des guillemets supplémentaires pour insérer ces 3 espaces alors que les commentaires SE pressent les espaces contigus en un seul)Réponses:
Vous pouvez utiliser
sprintf
pour reformater$1
uniquement.Ex.
la source
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Pour déterminer la longueur la plus grande / la plus longue du premier champ, puis pour reformater les valeurs du champ en fonction de cette longueur, vous devrez effectuer deux passes distinctes sur le fichier.
(notez que le fichier d'entrée est spécifié deux fois sur la ligne de commande)
Pour les données que vous présentez, cela produirait
La première passe est gérée par le
FNR == NR
bloc, qui garde simplement la trace du champ le plus long vu jusqu'à présent (m
contient la longueur maximale vue) et passe à la ligne suivante.La deuxième passe est gérée par le dernier bloc, qui reformate le premier champ en utilisant
sprintf()
. La chaîne de format%-*s
signifie "une chaîne justifiée à gauche dont la largeur est donnée par l'argument entier avant l'argument qui contient la chaîne réelle".Cela pourrait évidemment être étendu pour faire toutes les colonnes en transformant le scalaire
m
en un tableau qui contient la largeur maximale de chaque colonne:la source
La manière intelligente est ce que propose Steeldriver . La façon alambiquée inutilement est d'itérer sur chaque champ:
Mais juste
sprintf
$1
et en finir avec ça.la source
Dans Awk, vous pouvez utiliser un "*" pour générer une chaîne de format printf dynamique.
Si vous connaissez déjà la longueur, vous pouvez passer la longueur du champ pour la première colonne avec -v.
Remarque: si vous ne saviez pas quelle est la longueur de la première colonne, vous pouvez stocker les valeurs dans un tableau, puis trouver la longueur maximale des colonnes en cours de route et l'imprimer dans le bloc END.
la source