Как выровнять несколько строк с помощью echo или print

Как выровнять несколько строк с помощью echo или print

У меня есть скрипт, который проверяет смонтированную файловую систему на соответствие записи, указанной в fstab. Проблема, с которой я сталкиваюсь, заключается в том, чтобы сохранить выравнивание вывода.

Ниже представлен вывод скрипта:

/  is mounted OK
/boot  is mounted OK
/was8  is mounted OK
/was8/slogs  is mounted OK
/was8/cluster  is mounted OK
/was8/working  is mounted OK
/was8/app  is mounted OK
/was8/tools  is mounted OK
/was8/plugin  is mounted OK
/was8/coreproduct  is mounted OK
...

Я хочу, чтобы эти линии были выровнены, чтобы это выглядело так:

/  is mounted                       OK
/boot  is mounted                   OK
/was8  is mounted                   OK
/was8/slogs  is mounted             OK
/was8/cluster  is mounted           OK
/was8/working  is mounted           OK
/was8/app  is mounted               OK
/was8/tools  is mounted             OK
/was8/plugin  is mounted            OK
/was8/coreproduct  is mounted       OK
...

Я пробовал column и xargs, но не смог получить желаемый результат. Может кто-нибудь мне помочь с этим.

решение1

В общем случае при печати можно задать ширину строки формата printf. %-20sбудет напечатана строка в поле шириной 20 символов (*) , если только она не переполнится. %-20.20sсделает ее 20-символьной и отбросит всю выходящую за пределы часть.

(* Хотя, например, Bash's printfна самом деле считаетсябайты(Разницу можно увидеть с помощью символов, например, äв UTF-8.)

Так, например

printf "%-40s %s\n" "$mountpoint  is mounted" "$status"

сделает первую часть (как минимум) шириной в 40 символов:

/was8/coreproduct  is mounted            OK
...

Или, если вам необходимо выполнить постобработку входных данных, вы можете использовать Perl или awk:

perl -pe 's/(.*) +(\S+)$/ sprintf "%-40s %s", $1, $2 /e'  < file

awk '{s=$NF; sub(/ *[^ ]+ *$/, "", $0); printf "%-40s %s\n", $0, s}'  < file

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


Или, если вас не волнует сохранение разделения между полями в точности таким, каким оно было, более простое решение, прокомментированное @JJoaoбыло бы:

awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}' < file

Это дает следующий вывод. Обратите внимание, что двухпространственный пробел перед is mountedсворачивается в один. Это происходит, поскольку awkперестраивает все $0, когда NFили любое из полей изменяется.

/was8/coreproduct is mounted             OK

решение2

Немного запутывающего Perl:

perl -ne 'printf "%-40s %s", /(.*) (.*)/s'

решение3

Один из способов — ввести табуляцию перед кодом статуса, например:

<input rev | sed 's/ /\t/' | rev | column -s $'\t' -t

Выход:

/  is mounted                        OK
/boot  is mounted                    OK
/was8  is mounted                    OK
/was8/slogs  is mounted              OK
/was8/cluster  is mounted            OK
/was8/working  is mounted            OK
/was8/app  is mounted                OK
/was8/tools  is mounted              OK
/was8/plugin  is mounted             OK
/was8/coreproduct  is mounted        OK
/was8/ihs  is mounted                OK
/was8/backup  is mounted             OK
/was8/ihs/logs  is mounted           OK
/was8/wsdm  is mounted               OK
/was8/ws  is mounted                 OK
/was8/ihs/logs/analysis  is mounted  OK

решение4

Это также можно сделать очень легко с помощью утилиты столбцов. Ключ в том, чтобы включить какой-то отличительный маркер между вашими «столбцами». Например, если пробел является отличительным маркером, то column -s ' ' -o ' ' -tбудет идеально выровнен по пробелам.

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

column -s <Separator String> -o <Separator String in Output> -t

Это обобщение ответа на основе табуляции, но не требует обязательной вставки табуляции.

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