
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 sed
oder awk
ein 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.