クラスターから値を収集するスクリプトがあります。場合によっては、値に複数の行があります。データの配置方法を指定するprintf形式がありますが、複数行が考慮されていないため、間隔が偏っています。
The data should look like this:
Service Group AutoStart List System List
foo sys1 sys1
sys2 sys2
代わりにこのように見えます
Service Group AutoStart List System List
foo sys1
sys2 sys1
sys2
AutoStartリストとシステムリストは同一である必要がありますが、その事実に関係なく、値を正しい列に強制する方法がわかりません。
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}"
多分次のようなもの:
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構文)。または、POSIXly、/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
dash
と yash
を除いて、サブシェルによって供給されるパイプの代わりに一時ファイルを使用するため、(より移植性が高いことに加えて)より効率的である可能性があります。
それらがすべて毎回1行に収まる場合、これらはいくつかの簡単な方法です。あなたがこれをあなたが求めている正確な方法にしたいのなら、それは列を正しく並べるためにより多くの努力を要するでしょう。基本的な考え方は次のとおりです。
#!/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
あなたが望んでいる方法でこれを行うために私が知っている最良の方法は厄介です。その後でも、出力をさらに調整して正しく整列させることができます。
変数から新しい行を削除できます。
var=$(echo "$var" | tr -d '\n')