
¿Existe una manera fácil de alinear el texto en el centro con relleno en ambos lados, siendo el ancho de la columna la línea más larga desde la entrada?
Por ejemplo, esto:
aaa
bbbb
c
ddddd
ee
se convertirá en esto (los puntos representan espacios):
.aaa.
bbbb.
..c..
ddddd
.ee..
Cualquier herramienta está bien. Ya sea sed
o awk
un montón de coreutils
herramientas.
Editar: Creo que algunos de ustedes no entendieron bien el resultado. La salida se rellena conespacios, no puntos. He usado puntos aquí solo para que quede más claro.
Respuesta1
Yo usaría vim. Desde el modo normal:
:%center 5
...actuará en cada línea del archivo (ese es el significado de %
en este caso), centrándolo en cinco caracteres (denominados columnas en la documentación de vim). Esto actuará exactamente como lo describe. Para obtener la línea más larga de un archivo (para usar en el comando central), use wc -L file.txt
; o dentro de vim:
:! wc -L %
Desafortunadamente, esto no está disponible en vanilla vi, pero como está etiquetado como 'linux', es probable que al menos tengas vim en tus repositorios.
También puedes hacer esto en una línea con:
vim file.txt -c '%center 5' -c 'wq' &> /dev/null
...pero estoy seguro de que esa no es la forma más rápida de hacer las cosas.
Respuesta2
Aquí tienes una forma de hacerlo con awk (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"
}
Ejecútelo así:
awk -f pad.awk infile infile
Producción:
.aaa.
bbbb.
..c..
ddddd
.ee..
Si tiene GNU wc disponible, la línea más larga se puede encontrar de manera más eficiente conwc -L
. Es decir, elimine la primera línea depad.awky ejecuta awk así:
awk -f pad.awk M=$(wc -L < infile) infile
###Actualizar
Me perdí la parte sobre las cadenas con espacio acolchado. De todos modos, es bastante sencillo permitir un carácter de relleno variable. Aquí hay un ejemplo completo basado en las ideas anteriores:
# 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"
}
Ejemplo:
awk -v M=$(wc -L < infile) -v D=_ -f pad.awk infile
Producción:
_aaa_
bbbb_
__c__
ddddd
_ee__
Respuesta3
Aquí está mi solución, como se publicó en micomentar la respuesta de Thor:
awk -v M="`wc -L file`" '{ printf "%*s%*s", (M+length)/2, $0, (M-length+1)/2+1, "\n" }' < file
Siento que resuelve el problema de manera elegante y sucinta y, por lo tanto, lo vuelvo a publicar como respuesta.
Respuesta4
Con Python:
#!/usr/bin/env python
with open('input.txt') as file:
for line in file:
l = line.strip()
print l.center(5,'.'),"\n",
Nota: si está utilizando la versión anterior de Python inferior a 2.7, esto no funcionará.
Misma salida:
rahul@home-pc:~/work$ python format_center.py
.aaa.
.bbbb
..c..
ddddd
..ee.