Ich habe ein Skript, das Werte aus einem Cluster sammelt. Die Werte haben in einigen Fällen mehrere Zeilen. Ich habe ein printf-Format, das angibt, wie die Daten positioniert werden sollen. Es berücksichtigt jedoch nicht mehrere Zeilen und daher ist der Abstand verzerrt.
The data should look like this:
Service Group AutoStart List System List
foo sys1 sys1
sys2 sys2
Stattdessen sieht es so aus
Service Group AutoStart List System List
foo sys1
sys2 sys1
sys2
Die AutoStart-Liste und die Systemliste sollten identisch sein, trotzdem habe ich noch nicht herausgefunden, wie ich die Werte in die richtigen Spalten zwingen kann.
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}"
Antwort1
Vielleicht so etwas wie:
svcgroup='foo' autostrtlist=$'sys1\nsys2' hosts=$'sys1\nsys2'
paste <(printf '%s\n' "$svcgroup") \
<(printf '%s\n' "$autostrtlist") \
<(printf '%s\n' "$hosts") | expand -t30
(ksh93/zsh/bash-Syntax). Oder POSIX-mäßig auf einem System mit /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
Außer mit dash
,yash
und aktuelle Versionen von bash
, die temporäre Dateien anstelle von Pipes verwenden, die von Subshells gespeist werden, und daher wahrscheinlich effizienter sind (und außerdem portabler sind).
Antwort2
Sie können beliebige neue Zeilen aus einer Variablen entfernen.
var=$(echo "$var" | tr -d '\n')
Antwort3
Wenn sie jedes Mal alle in eine Zeile passen, sind dies einige einfache Möglichkeiten. Wenn Sie dies genau so tun möchten, wie Sie es verlangen, ist mehr Aufwand erforderlich, um die Spalten richtig auszurichten. Hier ist die Grundidee:
#!/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
Der beste Weg, den ich kenne, um dies so zu tun, wie Sie es möchten, ist chaotisch. Selbst danach möchten Sie die Ausgabe möglicherweise noch weiter verfeinern, damit sie richtig ausgerichtet ist.