So richten Sie mehrere Zeilen mit Echo oder Druck aus

7

Ich habe ein Skript, das das gemountete Dateisystem mit dem unter fstab aufgeführten Eintrag vergleicht. Das Problem, mit dem ich hier konfrontiert bin, besteht darin, die Ausgabe ausgerichtet zu halten.

Unten ist die Skriptausgabe:

/  is mounted OK
/boot  is mounted OK
/was8  is mounted OK
/was8/slogs  is mounted OK
/was8/cluster  is mounted OK
/was8/working  is mounted OK
/was8/app  is mounted OK
/was8/tools  is mounted OK
/was8/plugin  is mounted OK
/was8/coreproduct  is mounted OK
...

Ich möchte diese Linie ausgerichtet halten, damit sie so aussieht:

/  is mounted                       OK
/boot  is mounted                   OK
/was8  is mounted                   OK
/was8/slogs  is mounted             OK
/was8/cluster  is mounted           OK
/was8/working  is mounted           OK
/was8/app  is mounted               OK
/was8/tools  is mounted             OK
/was8/plugin  is mounted            OK
/was8/coreproduct  is mounted       OK
...

Ich habe versucht, Spalte und Xargs nicht das gewünschte Ergebnis zu erhalten. Kann mir jemand dabei helfen.

Kamal Asdeo
quelle
Hallo Freund, Perl Vorschlag funktioniert für mich, außer die / Dateisystem Rest wird alles perfekt ausgerichtet, Es gibt zusätzliche Registerkarte für / Dateisystem Ok Status und andere Dateisysteme
Kamal Asdeo

Antworten:

12

Im Allgemeinen können Sie beim Drucken die Breite in der Formatzeichenfolge auf festlegen printf. %-20swürde eine Zeichenfolge in ein Feld mit einer Breite von 20 Zeichen (*) drucken , es sei denn, sie läuft über. %-20.20swürde es 20 Zeichen machen und jeden überfüllten Teil fallen lassen.

(* Obwohl zB Bashs printftatsächlich Bytes zählen . Der Unterschied kann mit Zeichen wie äin UTF-8 gesehen werden.)

Also zB

printf "%-40s %s\n" "$mountpoint  is mounted" "$status"

würde den ersten Teil (mindestens) 40 Zeichen breit machen:

/was8/coreproduct  is mounted            OK
...

Wenn Sie eine solche Eingabe nachbearbeiten müssen, können Sie auch Perl oder awk verwenden:

perl -pe 's/(.*) +(\S+)$/ sprintf "%-40s %s", $1, $2 /e'  < file

awk '{s=$NF; sub(/ *[^ ]+ *$/, "", $0); printf "%-40s %s\n", $0, s}'  < file

Beide trennen im Grunde die letzte Nicht-Leerzeichen-Zeichenfolge und drucken dann die beiden Teile mit dem ersten auf ein Feld mit fester Breite.


Wenn Sie die Trennung zwischen den Feldern nicht genau so beibehalten möchten , wie sie waren, wäre eine einfachere Lösung, die von @ JJoao kommentiert wird :

awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}' < file

Das erzeugt die folgende Ausgabe. Beachten Sie, dass das Leerzeichen mit zwei Leerzeichen zuvor is mountedauf eins reduziert ist. Dies geschieht, da awkdas Ganze neu erstellt wird, $0wenn NFoder eines der Felder geändert wird.

/was8/coreproduct is mounted             OK
ilkkachu
quelle
cool +1; oder ..awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}'
JJoao
1
@JJoao, ja, das ist der einfache Weg, aber es bricht die Zwei-Raum-Trennung vorher zusammen is mounted:) Wahrscheinlich eine gute Idee, das auf jeden Fall einzuschließen .
Ilkkachu
3
Beachten Sie, dass printf "%.20s"nur eine Zeichenfolge mit einer Breite von 20 Zeichen mit zshoder gedruckt wird fish printf. Bei anderen Implementierungen ist es 20 Byte breit, wie es POSIX (unangemessen) erfordert. printfBeachten Sie bei der integrierten Version von ksh93 auch, printf "%20Ls"dass die Breite die Anzeigebreite ist (unter Berücksichtigung von Zeichen mit der Breite Null oder der doppelten Breite). Für awk wird YMMV je nach Implementierung mit perlverwendet -Mopen=locale, um mit Zeichen im Zeichensatz des Gebietsschemas zu arbeiten.
Stéphane Chazelas
6

Nur ein bisschen Perl verschleiern:

perl -ne 'printf "%-40s %s", /(.*) (.*)/s'
JJoao
quelle
1
Das ist gar nicht so schlecht, was das verschleierte Perl betrifft.
Ilkkachu
... auf jeden Fall werden wir hinterhältig ☺
JJoao
4

Eine Möglichkeit besteht darin, vor dem Statuscode eine Registerkarte einzufügen, z.

<input rev | sed 's/ /\t/' | rev | column -s $'\t' -t

Ausgabe:

/  is mounted                        OK
/boot  is mounted                    OK
/was8  is mounted                    OK
/was8/slogs  is mounted              OK
/was8/cluster  is mounted            OK
/was8/working  is mounted            OK
/was8/app  is mounted                OK
/was8/tools  is mounted              OK
/was8/plugin  is mounted             OK
/was8/coreproduct  is mounted        OK
/was8/ihs  is mounted                OK
/was8/backup  is mounted             OK
/was8/ihs/logs  is mounted           OK
/was8/wsdm  is mounted               OK
/was8/ws  is mounted                 OK
/was8/ihs/logs/analysis  is mounted  OK
Thor
quelle
1
Ich denke, Sie könnten auch so etwas wie sed -Ee 's/(.*) +/\1\t/'die letzten Leerzeichen durch die Registerkarte ersetzen. (Von hier gestohlen: unix.stackexchange.com/q/187889/170373 )
ilkkachu
@ikkachu, das ist das gleiche wie sed 's/\(.*\) /\1\t/'das, das " +"immer nur einem Feld entspricht, da das vorhergehende .*alle anderen gefressen hat.
Stéphane Chazelas
@ StéphaneChazelas, guter Punkt. Und natürlich hatte die Eingabe hier nicht einmal mehrere Leerzeichen vor dem OK. Der Hauptpunkt war der Versuch, das revs zu vermeiden .
Ilkkachu
Linux_FS_CHECK () {mount | egrep "ext | vxfs | lofs | xfs" | awk '{print $ 3}'> / tmp / Postcheck während der Lesezeile do cat / tmp / Postcheck | grep $ line> / dev / null wenn [$? -eq 0]; dann echo -e "$ line Dateisystem ist gemountet $ green (OK)"; $ reset else echo -e "!!! Warnung !!! $ line Dateisystem ist nicht gemountet $ red (Failed)"; $ reset fi done </ tmp / Precheck} mount | egrep "ext | vxfs | lofs | xfs" | awk '{print $ 3}'> / tmp / Precheck Linux_FS_CHECK Dies ist ein Skript, das ich aus meinem Pre & Post-Che gezogen habe
Kamal Asdeo
@ KamalAsdeo: Ich verstehe nicht
Thor
1

Dies kann auch sehr einfach mit dem Spalten-Dienstprogramm durchgeführt werden. Der Schlüssel besteht darin, eine Art Unterscheidungsmarker zwischen Ihren 'Spalten' einzufügen. Wenn beispielsweise das Leerzeichen der Unterscheidungsmarker ist, werden die column -s ' ' -o ' ' -tLeerzeichen perfekt ausgerichtet.

Ich benutze dies häufig und habe sogar einige nette Vim-Makros erstellt, die es zum Ausrichten von Code verwenden. Die allgemeine Syntax, die Sie möchten, lautet:

column -s <Separator String> -o <Separator String in Output> -t

Dies ist eine Verallgemeinerung der tabulatorbasierten Antwort, erfordert jedoch nicht unbedingt das Einfügen von Tabulatoren.

LambdaBeta
quelle
Welche Version von columnist das?
Thor
Ich vermute GNU. Ich bin auf mobilem Geldautomaten und es ist schwieriger zu überprüfen, aber es funktioniert unter den meisten Linuxen, die ich benutze.
LambdaBeta