複数行の変数を列に印刷する

複数行の変数を列に印刷する

クラスターから値を収集するスクリプトがあります。値には、場合によっては複数行があります。データの配置方法を指定する 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}"

答え1

たとえば次のようなもの:

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 構文)。または、POSIX では、次のシステムの場合/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

ただしdashyashおよびの最近のバージョンではbash、サブシェルによって供給されるパイプの代わりに一時ファイルを使用するため、より効率的である可能性があります (さらに、移植性も高くなります)。

答え2

変数から新しい行を削除できます。

var=$(echo "$var" | tr -d '\n')

答え3

毎回 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

私が知っている限り、あなたが望む方法でこれを行う最善の方法は、乱雑な方法です。その後でも、出力をさらに調整して正しく整列させる必要があるかもしれません。

関連情報