Text zentriert ausrichten, mit beidseitiger Polsterung

Text zentriert ausrichten, mit beidseitiger Polsterung

Gibt es eine einfache Möglichkeit, Text mit Abstand auf beiden Seiten zentriert auszurichten, wobei die Spaltenbreite der längsten Zeile der Eingabe entspricht?

Zum Beispiel dies:

aaa
bbbb
c
ddddd
ee

wird zu Folgendem (die Punkte stellen Leerzeichen dar):

.aaa.
bbbb.
..c..
ddddd
.ee..

Jedes Werkzeug ist geeignet. Egal ob es ein Werkzeug sedoder awkein Werkzeugsatz ist coreutils.

Bearbeiten: Ich glaube, einige von Ihnen haben die Ausgabe missverstanden. Die Ausgabe ist aufgefüllt mitRäume, keine Punkte. Ich habe hier Punkte verwendet, um es deutlicher zu machen.

Antwort1

Ich würde vim verwenden. Aus dem normalen Modus:

:%center 5

...wirkt auf jede Zeile in der Datei (das ist %in diesem Fall die Bedeutung von ) und zentriert sie auf fünf Zeichen (in der Vim-Dokumentation als Spalten bezeichnet). Dies funktioniert genau so, wie Sie es beschreiben. Um die längste Zeile in einer Datei zu erhalten (zur Verwendung im Befehl center), verwenden Sie wc -L file.txt; oder innerhalb von Vim:

:! wc -L %

Leider ist dies in Vanilla vi nicht verfügbar, aber da dies mit „Linux“ gekennzeichnet ist, ist es wahrscheinlich, dass Sie vim zumindest in Ihren Repositories haben.

Sie können dies auch in einer Zeile tun mit:

vim file.txt -c '%center 5' -c 'wq' &> /dev/null

...aber ich bin sicher, dass das nicht der schnellste Weg ist, die Dinge zu erledigen.

Antwort2

Hier ist eine Möglichkeit, wie Sie dies mit awk tun könnten (pad.awk):

# Determine length of longest line
FNR == NR { if(length > M) M = length; next }

# Pad each line according current line length (L) and longest line (M)
{
  L = M - length;
  for(i=1; i<=int(L/2); i++)
    printf "."
  printf "%s", $0
  for(i=1; i<=int(L/2+.5); i++)
    printf "."
  printf "\n"
}

Führen Sie es wie folgt aus:

awk -f pad.awk infile infile

Ausgabe:

.aaa.
bbbb.
..c..
ddddd
.ee..

Wenn Sie GNU wc zur Verfügung haben, kann die längste Zeile effizienter mit gefunden werden wc -L. Das heißt, löschen Sie die erste Zeile vonpad.awkund führen Sie awk wie folgt aus:

awk -f pad.awk M=$(wc -L < infile) infile

###Aktualisieren

Ich habe den Teil über mit Leerzeichen aufgefüllte Zeichenfolgen übersehen. Wie dem auch sei, es ist ziemlich unkompliziert, ein variables Füllzeichen zuzulassen. Hier ist ein vollständiges Beispiel, das auf den oben genannten Ideen basiert:

# Set padding character to the default (" ") if it was not set with -v
# Set ORS to "" to make printing easier
BEGIN { if(D == "") D = " "; ORS = "" }

# Pad each line according current line length (L) and longest line (M)
{
  L = M - length;
  for(i=1; i<=int(L/2); i++)
    print D
  print $0
  for(i=1; i<=int(L/2+.5); i++)
    print D
  print "\n"
}

Beispiel:

awk -v M=$(wc -L < infile) -v D=_ -f pad.awk infile

Ausgabe:

_aaa_
bbbb_
__c__
ddddd
_ee__

Antwort3

Hier ist meine Lösung, wie in meinemKommentar zu Thors Antwort:

awk -v M="`wc -L file`" '{ printf "%*s%*s", (M+length)/2, $0, (M-length+1)/2+1, "\n" }' < file

Ich bin der Meinung, dass es das Problem elegant und prägnant löst, und poste es daher noch einmal als Antwort.

Antwort4

Mit Python:

#!/usr/bin/env python

with open('input.txt') as file:
    for line in file:
        l = line.strip()
        print l.center(5,'.'),"\n",

Hinweis: Wenn Sie eine ältere Python-Version unter 2.7 verwenden, funktioniert dies nicht.

Gleiche Ausgabe:

rahul@home-pc:~/work$ python format_center.py
.aaa. 
.bbbb 
..c.. 
ddddd 
..ee.

verwandte Informationen