Como alinhar várias linhas com eco ou impressão

6

Eu tenho um script que verifica o sistema de arquivos montado em relação à entrada listada em fstab, o problema que estou enfrentando aqui é manter o alinhamento da saída.

Abaixo está a saída do script:

/  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
...

Eu quero manter essas linhas alinhadas para que pareçam assim:

/  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
...

Eu tentei column e xargs incapazes de obter o resultado desejado. Alguém pode me ajudar com isso.

    
por Kamal Asdeo 01.06.2018 / 11:16

4 respostas

12

Em geral, quando você está imprimindo, pode definir a largura na string de formato como printf . %-20s imprimia uma string em um campo com 20 caracteres (*) de largura, a menos que estourasse. %-20.20s teria 20 caracteres e eliminaria qualquer parte transbordante.

(* Embora, por exemplo, o printf do Bash realmente conte bytes . A diferença pode ser vista com caracteres como ä em UTF-8.)

Então, por exemplo,

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

teria a primeira parte (pelo menos) 40 caracteres de largura:

/was8/coreproduct  is mounted            OK
...

Ou, se você precisar pós-processar uma entrada como essa, pode usar o Perl ou o awk:

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

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

Ambos basicamente separam a última string que não é espaço em branco e, em seguida, imprimem as duas partes com a primeira em um campo de largura fixa.

Ou, se você não se importa em manter exatamente a separação entre os campos, uma solução mais simples comentada por @ JJao seria:

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

Isso produz a saída abaixo. Observe que o espaço em branco de dois espaços antes de is mounted é reduzido para um. Isso acontece porque awk reconstrói todo o $0 quando NF ou qualquer um dos campos é modificado.

/was8/coreproduct is mounted             OK
    
por 01.06.2018 / 11:33
6

Apenas um pouco de ofuscante Perl:

perl -ne 'printf "%-40s %s", /(.*) (.*)/s'
    
por 01.06.2018 / 12:44
4

Uma maneira é apresentar uma guia antes do código de status, por exemplo:

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

Saída:

/  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
    
por 01.06.2018 / 11:22
1

Isso também pode ser feito facilmente com o utilitário de coluna. A chave é incluir algum tipo de marcador de diferenciação entre suas "colunas". Por exemplo, se o espaço for o marcador de diferenciação, column -s ' ' -o ' ' -t será perfeitamente alinhado nos espaços.

Eu uso isso com frequência e até fiz algumas macros vim legais que o utilizam para alinhar o código. A sintaxe geral que você quer é:

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

Esta é uma generalização da resposta baseada em guias, mas não requer necessariamente a inserção de guias.

    
por 01.06.2018 / 21:29