Imprime uma variável de múltiplas linhas em uma coluna

6

Eu tenho um script que coleta valores de um cluster. Os valores, em alguns casos, possuem várias linhas. Eu tenho um formato printf que especifica como os dados devem ser posicionados, no entanto, não leva em conta várias linhas e, portanto, o espaçamento é distorcido.

The data should look like this:

Service Group          AutoStart List          System List
foo                    sys1                    sys1
                       sys2                    sys2

Em vez disso, parece com isso

Service Group          AutoStart List          System List
foo                    sys1                    
sys2                    sys1
sys2

A lista AutoStart e a lista de sistemas devem ser idênticas, no entanto, independentemente desse fato, não descobri como forçar os valores nas colunas corretas.

sgheader="\n3[4m3[1m%-30s %-30s %-15s3[0m3[0m"
sgformat="\n%-30s %-30s %-15s"



printf "${sgheader}" "Service Group" "Autostart List" "System List" 
printf "${sgformat}" "${svcgroup}" "${autostrtlist}" "${hosts}"
    
por awreneau 23.06.2014 / 22:12

3 respostas

4

Talvez alguma coisa como:

svcgroup='foo' autostrtlist=$'sys1\nsys2' hosts=$'sys1\nsys2'
paste <(printf '%s\n' "$svcgroup") \
      <(printf '%s\n' "$autostrtlist") \
      <(printf '%s\n' "$hosts") | expand -t30

(sintaxe do ksh93 / zsh / bash). Ou, POSIXly, em um sistema com /dev/fd/x :

paste /dev/fd/3 3<<E3 /dev/fd/4 4<<E4 /dev/fd/5 5<<E5 | expand -t 30
$svcgroup
E3
$autostrtlist
E4
$hosts
E5

Exceto com dash e yash , esse usa arquivos temporários em vez de canos alimentados por subshells então é provável que seja mais eficiente (além de ser mais portátil).

    
por 23.06.2014 / 23:34
1

Você pode remover novas linhas de uma variável.

var=$(echo "$var" | tr -d '\n')
    
por 23.06.2014 / 23:33
1

Se todas elas caberem em uma linha todas as vezes, essas são algumas maneiras fáceis. Se você quiser isso da maneira exata que você está pedindo, vai ser preciso mais esforço para alinhar as colunas corretamente. Aqui está a ideia básica:

#!/bin/bash

inputA="foo"
inputB=$'sys1\nsys2\n'
inputC=$'sys1\nsys2\n'

sgheader="3[4m3[1m%-30s %-30s %-15s3[0m3[0m\n"
sgformat="%-30s %-30s %-15s\n"

printf "${sgheader}" "Service Group" "Autostart List" "System List"

# This shows two simple ways to do this which use concatenation but
# require that the result still fit in the same space as is used for
# a single line
columnA="$inputA"
columnB=$(echo "$inputB"|awk '{printf("%s,",$0)}'|sed 's/,.\s*$//')
columnC=$(echo "$inputC"|tr '\n' ',')

printf "${sgformat}" "${columnA}" "${columnB}" "${columnC}"

# This is a version which outputs like originally asked. It is much harder
# to tweak the formatting of this version though.
pr -tm <(printf '%s\n' "$inputA") <(printf '%s\n' "$inputB") \
       <(printf '%s\n' "$inputC") | expand -t10

A melhor maneira que eu conheço para fazer isso do jeito que você está querendo é confuso. Mesmo depois disso, você pode querer refinar ainda mais a saída para alinhar corretamente.

    
por 23.06.2014 / 23:29