Tenho um script que coleta valores de um cluster. Os valores, em alguns casos, possuem múltiplas linhas. Eu tenho um formato printf que especifica como os dados devem ser posicionados, porém não leva em consideração 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 assim
Service Group AutoStart List System List
foo sys1
sys2 sys1
sys2
A Lista AutoStart e a Lista do Sistema devem ser idênticas, porém, independentemente desse fato, não descobri como forçar os valores nas colunas corretas.
sgheader="\n\033[4m\033[1m%-30s %-30s %-15s\033[0m\033[0m"
sgformat="\n%-30s %-30s %-15s"
printf "${sgheader}" "Service Group" "Autostart List" "System List"
printf "${sgformat}" "${svcgroup}" "${autostrtlist}" "${hosts}"
Responder1
Talvez algo 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 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
,yash
e versões recentes do bash
, que usam arquivos temporários em vez de pipes alimentados por subshells, portanto, provavelmente será mais eficiente (além de ser mais portátil).
Responder2
Você pode remover quaisquer novas linhas de uma variável.
var=$(echo "$var" | tr -d '\n')
Responder3
Se todos eles couberem sempre em uma linha, essas são algumas maneiras fáceis. Se você quiser fazer isso exatamente da maneira que está solicitando, será necessário 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="\033[4m\033[1m%-30s %-30s %-15s\033[0m\033[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 conheço de fazer isso do jeito que você quer é bagunçada. Mesmo depois disso, você pode querer refinar ainda mais a saída para alinhá-la corretamente.