Ich verstehe, wie man die printf-Funktion von awk verwendet, möchte aber nicht jedes Feld angeben.
Angenommen, dies ist meine Datei:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Ich möchte es so formatieren, dass das erste Feld jedes Datensatzes die Breite von c11 hat - die längste Zelle im ersten Feld:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Ich verstehe, dass ich angeben könnte:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Nehmen wir an, ich weiß, wie breit die erste Spalte sein soll, aber ich weiß NICHT, wie viele Felder sich in der Datei befinden. Grundsätzlich möchte ich so etwas machen wie:
... '{printf "%-3s|", $1}'
... und drucken Sie dann die restlichen Felder im Originalformat aus.
awk
text-formatting
printf
Kayli O'Keefe
quelle
quelle
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(Hier werden zusätzliche Anführungszeichen hinzugefügt, um diese drei Leerzeichen einzufügen, wenn die SE-Kommentare zusammenhängende Leerzeichen in ein einziges zusammenfassen.)Antworten:
Sie können nur
sprintf
zum Neuformatieren verwenden$1
.Ex.
quelle
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Um die größte / längste Länge des ersten Felds zu ermitteln und dann die Werte im Feld entsprechend dieser Länge neu zu formatieren, müssen Sie zwei separate Durchgänge über die Datei durchführen.
(Beachten Sie, dass die Eingabedatei zweimal in der Befehlszeile angegeben wird.)
Für die Daten, die Sie präsentieren, würde dies erzeugen
Der erste Durchgang wird vom
FNR == NR
Block verarbeitet, der einfach das längste bisher gesehene Feld verfolgt (m
enthält die maximal gesehene Länge) und zur nächsten Zeile springt.Der zweite Durchgang wird vom letzten Block behandelt, der das erste Feld mit neu formatiert
sprintf()
. Die Formatzeichenfolge%-*s
bedeutet "eine linksbündige Zeichenfolge, deren Breite durch das Ganzzahlargument vor dem Argument angegeben wird, das die tatsächliche Zeichenfolge enthält".Dies könnte natürlich auf alle Spalten erweitert werden, indem der Skalar
m
in ein Array umgewandelt wird, das die maximale Breite jeder Spalte enthält:quelle
Der intelligente Weg ist das, was Steeldriver vorgeschlagen hat . Der unnötig verschlungene Weg besteht darin, über jedes Feld zu iterieren:
Aber einfach
sprintf
$1
und fertig damit.quelle
In Awk können Sie ein "*" verwenden, um eine dynamische Zeichenfolge im printf-Format zu generieren.
Wenn Sie die Länge bereits kennen, können Sie die Feldlänge für die erste Spalte mit -v übergeben.
Hinweis: Wenn Sie nicht wissen, wie lang die erste Spalte ist, können Sie die Werte in einem Array speichern und dann die maximale Spaltenlänge ermitteln und alles im END-Block ausdrucken.
quelle