Выровнять текст по центру с отступами с обеих сторон

Выровнять текст по центру с отступами с обеих сторон

Есть ли простой способ выровнять текст по центру с отступами с обеих сторон, при этом ширина столбца должна соответствовать самой длинной строке ввода?

Например, это:

aaa
bbbb
c
ddddd
ee

превратится в это (точки обозначают пробелы):

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

Любой инструмент подойдет. Будь то sedили awkили куча coreutilsинструментов.

Редактировать: Я думаю, что некоторые из вас неправильно поняли вывод. Вывод дополненпространства, а не точки. Я использовал точки здесь просто для большей ясности.

решение1

Я бы использовал vim. Из обычного режима:

:%center 5

...будет действовать на каждую строку в файле (в данном случае это значение %), центрируя ее по пяти символам (в документации vim они называются столбцами). Это будет действовать именно так, как вы описываете. Чтобы получить самую длинную строку в файле (для использования в команде center), используйте wc -L file.txt; или в vim:

:! wc -L %

К сожалению, это недоступно в vanilla vi, но поскольку он помечен как «linux», то, скорее всего, vim есть, по крайней мере, в ваших репозиториях.

Вы также можете сделать это в одну строку:

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

...но я уверен, что это не самый быстрый способ решения проблемы.

решение2

Вот один из способов сделать это с помощью awk (пад.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"
}

Запустите его так:

awk -f pad.awk infile infile

Выход:

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

Если у вас есть GNU wc, самую длинную строку можно найти более эффективно с помощью wc -L. То есть, отбросьте первую строкупад.awkи запустите awk следующим образом:

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

###Обновлять

Я пропустил часть о строках с пробелами. В любом случае, довольно просто разрешить переменный символ заполнения. Вот полный пример, основанный на идеях выше:

# 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"
}

Пример:

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

Выход:

_aaa_
bbbb_
__c__
ddddd
_ee__

решение3

Вот мое решение, опубликованное в моемкомментарий к ответу Тора:

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

Я считаю, что это решает проблему элегантно и лаконично, поэтому я публикую его повторно в качестве ответа.

решение4

С Python:

#!/usr/bin/env python

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

Примечание: если вы используете Python Old версии ниже 2.7, то это не сработает.

Тот же вывод:

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

Связанный контент