
Existe uma maneira fácil de alinhar o texto ao centro com preenchimento em ambos os lados, sendo a largura da coluna a linha mais longa da entrada?
Por exemplo, isto:
aaa
bbbb
c
ddddd
ee
vai se transformar nisso (os pontos representam espaços):
.aaa.
bbbb.
..c..
ddddd
.ee..
Qualquer ferramenta está bem. Seja isso sed
ou awk
um monte de coreutils
ferramentas.
Editar: Acho que alguns de vocês entenderam mal o resultado. A saída é preenchida comespaços, não pontos. Usei pontos aqui apenas para deixar mais claro.
Responder1
Eu usaria o vim. Do modo normal:
:%center 5
... atuará em todas as linhas do arquivo (esse é o significado de %
neste caso), centralizando-o em cinco caracteres (referidos como colunas na documentação do vim). Isso funcionará exatamente como você descreve. Para obter a linha mais longa em um arquivo (para uso no comando central), use wc -L file.txt
; ou dentro do vim:
:! wc -L %
Infelizmente, isso não está disponível no vanilla vi, mas como está marcado como 'linux', é provável que você tenha pelo menos o vim em seus repositórios.
Você também pode fazer isso em uma linha com:
vim file.txt -c '%center 5' -c 'wq' &> /dev/null
...mas tenho certeza de que essa não é a maneira mais rápida de fazer as coisas.
Responder2
Aqui está uma maneira de fazer isso com o 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"
}
Execute assim:
awk -f pad.awk infile infile
Saída:
.aaa.
bbbb.
..c..
ddddd
.ee..
Se você tiver o GNU wc disponível, a linha mais longa poderá ser encontrada com mais eficiência com wc -L
. Ou seja, elimine a primeira linha dopad.awke execute awk assim:
awk -f pad.awk M=$(wc -L < infile) infile
###Atualizar
Eu perdi a parte sobre strings preenchidas com espaço. De qualquer forma, é bastante simples permitir um caractere de preenchimento variável. Aqui está um exemplo completo baseado nas ideias acima:
# 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"
}
Exemplo:
awk -v M=$(wc -L < infile) -v D=_ -f pad.awk infile
Saída:
_aaa_
bbbb_
__c__
ddddd
_ee__
Responder3
Aqui está a minha solução, conforme postado no meucomente a resposta de Thor:
awk -v M="`wc -L file`" '{ printf "%*s%*s", (M+length)/2, $0, (M-length+1)/2+1, "\n" }' < file
Sinto que isso resolve o problema de maneira elegante e sucinta e, portanto, estou republicando-o como resposta.
Responder4
Com Python:
#!/usr/bin/env python
with open('input.txt') as file:
for line in file:
l = line.strip()
print l.center(5,'.'),"\n",
Nota: se você estiver usando a versão antiga do Python abaixo de 2.7, isso não funcionará.
Mesma saída:
rahul@home-pc:~/work$ python format_center.py
.aaa.
.bbbb
..c..
ddddd
..ee.