Tengo un script que recopila valores de un clúster. Los valores, en algunos casos, tienen varias líneas. Tengo un formato printf que especifica cómo se deben colocar los datos; sin embargo, no tiene en cuenta varias líneas y, por lo tanto, el espaciado está sesgado.
The data should look like this:
Service Group AutoStart List System List
foo sys1 sys1
sys2 sys2
En cambio se ve así
Service Group AutoStart List System List
foo sys1
sys2 sys1
sys2
La Lista de inicio automático y la Lista del sistema deberían ser idénticas; sin embargo, independientemente de ese hecho, no he descubierto cómo forzar los valores en las columnas correctas.
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}"
Respuesta1
Quizás 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
(sintaxis ksh93/zsh/bash). O, POSIXly, en un sistema con /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
Excepto con dash
,yash
y versiones recientes de bash
, que utilizan archivos temporales en lugar de tuberías alimentadas por subcapas, por lo que es probable que sea más eficiente (además de ser más portátil).
Respuesta2
Puede eliminar cualquier línea nueva de una variable.
var=$(echo "$var" | tr -d '\n')
Respuesta3
Si todos caben en una línea cada vez, estas son algunas formas sencillas. Si desea hacer esto exactamente de la manera que lo solicita, requerirá más esfuerzo alinear las columnas correctamente. Aquí está la idea 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
La mejor manera que conozco de hacer esto de la manera que deseas es complicada. Incluso después de eso, es posible que desees refinar aún más la salida para alinearla correctamente.