2016-03-21 18 views
3

Ich mag würde folgende Ausgabe erzeugen:Formatierung Ausgabe mit printf: Kürzen oder Polsterung

> Avril Stewart 99 54 
> Sally Kinghorn 170 60 
> John Young  195 120 
> Yutte Schim... 250 40 

Wie Sie sehen können, Namen kürzer als 14 Zeichen sind mit Leerzeichen aufgefüllt. Namen, die länger als 15 Zeichen sind, werden abgeschnitten: "Yutte Schimmelpenninck" schneidet auf "Yutte Schim ..." ab. Hier

ist, was ich habe versucht, diese (die Variablen $name, $height und $weight werden aus Dateien extrahiert und eine Schleife führt die printf Befehl für jede Datei-Daten) zu erreichen:

printf '%-14s -%3s -%3s\n' "$name" "$height" "$weight" 
> Avril Stewart 99 54 
> Sally Kinghorn 170 60 
> John Young  195 120 
> Yutte Schimmelpenninck 250 40 

A printf ein -Liner ist die gewünschte Lösung.

Welcher Code erzeugt den ersten Ausgangsblock?

+0

Woher kommen die Daten kommen? –

+0

Und bist du sicher, dass du das ausprobiert hast? Ich würde denken, dass Ihre Format-Zeichenfolge "-" zwischen den Feldern erzeugen würde. –

+0

Die Felder werden aus einer Datei unbekannter Länge eingelesen. Der tatsächlich ausgegebene Befehl lautet printf '% -14s -% 3s -% 3s \ n' $ name $ weight $ height. –

Antwort

5

Vor dem Befehl printf möchten Sie überprüfen, ob ein Name länger als 14 Zeichen ist, und wenn ja, schneiden Sie ihn ab und ersetzen Sie die letzten drei Zeichen durch Punkte. Dieser Befehl funktioniert das:

((${#name} > 14)) && name="${name:0:11}..." 

Es name mit seinen ersten elf Zeichen ersetzt und fügt ....

Sie haben auch die printf Format-String zu beheben: statt

'%-14s -%3s -%3s\n' 

hat

'%-14s %-3s -%-3s\n' 

oder Sie Ergebnisse werden wie

Avril Stewart - 99 - 54 

Vielleicht wurde nur ein Tippfehler, da Ihre Beispielausgabe keine Bindestriche hatte.

Alles in allem:

$ name='Avril Stewart'; weight=99; height=54 
$ ((${#name} > 14)) && name="${name:0:11}..." 
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height 
Avril Stewart 99 54 
$ name='Sally Kinghorn'; weight=170; height=60 
$ ((${#name} > 14)) && name="${name:0:11}..." 
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height 
Sally Kinghorn 170 60 
$ name='Yutte Schimmelpeninck'; weight=250; height=40 
$ ((${#name} > 14)) && name="${name:0:11}..." 
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height 
Yutte Schim... 250 40 

Also, wenn Sie diese aus einer Datei lesen, zum Beispiel durch Komma getrennt, dann würden Sie mit einer Schlaufe am Ende wie folgt:

while IFS=, read -r name weight height; do 
    ((${#name} > 14)) && name="${name:0:11}..." 
    printf '%-14s %-3s %-3s\n' "$name" $weight $height 
done < inputFile 

was

Avril Stewart 99 54 
Sally Kinghorn 170 60 
John Young  195 120 
Yutte Schim... 250 40 

ich glaube es nicht‘ s möglich in einem Einzeiler. Ich experimentierte mit dem ternären Operator und versuchte, so etwas wie

printf '%s\n' $((${#name} > 14 ? "${name:0:11}..." : "$name")) 

aber das Problem hier ist, dass es nur für ganze Zahlen arbeitet und Strings auf Null in arithmetischen Kontext erweitern.

3

eine idiomatische awk Version

$ awk  '{v=$1 FS $2} 
    length(v)>14{v=substr(v,1,11)"..."} 
       {printf "%-15s %-3d %-3d\n",v,$3,$4}' file  

Avril Stewart 99 54 
Sally Kinghorn 170 60 
John Young  195 120 
Yutte Schim... 250 40 

sein wird, wenn Sie das - Zeichen in% -3D entfernen, werden Zahlen rechts wie üblich ausgerichtet werden, was jedoch das Format Sie gefragt.

0

Dies ist eine Teilantwort - Das Ignorieren der letzten „...“:

awk '{printf "%-14.14s %-3d %-3d\n",$1 FS $2,$3,$4}' 

wo %-14.14s ist die Polsterung + gestutzt Formatierung des Namen