ハイパーバイザーで実行されている仮想マシンの詳細を含むファイルがあります。いくつかのコマンドを実行し、出力をファイルにリダイレクトします。データは次の形式にすることができます。
Virtual Machine : OL6U5
ID : 0004fb00000600003da8ce6948c441bb
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U6
ID : 0004fb00000600003da8ce6948c441bc
Status : Running
Memory : 65536
Uptime : 17565 Minutes
Server : MyOVS2.vmorld.com
Pool : NON-HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U7
ID : 0004fb00000600003da8ce6948c441bd
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
50を超えるVMを実行している一部のハイパーバイザーでは、この出力はハイパーバイザーによって異なります。上記のファイルは3つのVMのみを実行するハイパーバイザーの例にすぎないため、リダイレクトされたファイルには複数の(N台のVM)に関する情報が含まれると予想されます。
awk/sed またはシェルスクリプトを使用して、次の形式でこの詳細をインポートする必要があります。
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U5 0004fb00000600003da8ce6948c441bb Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U6 0004fb00000600003da8ce6948c441bc Running 65536 17565 MyOVS2.vmworld.com NON-HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U5 0004fb00000600003da8ce6948c441bd Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
答え1
お持ちの場合rs
(再発明)ユーティリティ可能であれば、次のことができます。
rs -Tzc: < input.txt
これは、ダイナミック列幅まで、質問で指定されたものとまったく同じ出力形式を提供します。
-T
入力データの転置-z
各列の最大値に基づいて列サイズを適切に調整します。-c:
入力フィールド区切り記号としてコロンを使用する
これはすべてのサイズのテーブルに適用されます。たとえば、次のようになります。
$ echo "Name:Alice:Bob:Carol
Age:12:34:56
Eyecolour:Brown:Black:Blue" | rs -Tzc:
Name Age Eyecolour
Alice 12 Brown
Bob 34 Black
Carol 56 Blue
$
rs
OS X(およびその他のBSDシステム)でデフォルトで有効になっています。次のコマンドを使用してUbuntu(およびdebianシリーズ)にインストールできます。
sudo apt-get install rs
答え2
編集する:単純な1行ループfor
から必要な数の出力ラインに拡張可能:
for ((i=1;i<=2;i++)); do cut -d: -f "$i" input | paste -sd: ; done | column -t -s:
元の答え:
プロセス置換を使用して、1行のコードで実行できますbash
。
paste -sd: <(cut -d: -f1 input) <(cut -d: -f2 input) | column -t -s:
この-s
オプションをpaste
使用すると、各ファイルを一度に処理します。:
セット区切り文字は、paste
フィールドをソートして書式を美しくする最後のオプションによって「キャプチャ」されます。-s
column
2つのプロセス置換のコマンドは、cut
それぞれ最初のフィールドと2番目のフィールドを取得します。
入力に空白行があっても構いません。column -t -s:
とにかく出力が削除されるからです。 (質問で指定された元の入力には空行がありましたが削除されました。上記のコマンドは空行に関係なく機能します。)
入力 - 上記のコマンドで「input」というファイルの内容:
Virtual_Machine:OL6U7
ID:0004fb00000600003da8ce6948c441bd
Status:Running
Memory:65536
Uptime:17103
Server:MyOVS1.vmworld.com
Pool:HA-POOL
HA:false
VCPU:16
Type:Xen PVM
OS:Oracle Linux 6
出力:
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U7 0004fb00000600003da8ce6948c441bd Running 65536 17103 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
答え3
ファイルを2回移動することが(大きな)問題ではない場合(1行だけがメモリに保存されます):
awk -F : '{printf("%s\t ", $1)}' infile
echo
awk -F : '{printf("%s\t ", $2)}' infile
ファイルパスが多い可能性がある一般的なフィールド数の場合:
#!/bin/bash
rowcount=2
for (( i=1; i<=rowcount; i++ )); do
awk -v i="$i" -F : '{printf("%s\t ", $i)}' infile
echo
done
しかし、真の普遍的な転置のためには、次のことが機能します。
awk '$0!~/^$/{ i++;
split($0,arr,":");
for (j in arr) {
out[i,j]=arr[j];
if (maxr<j){ maxr=j} # max number of output rows.
}
}
END {
maxc=i # max number of output columns.
for (j=1; j<=maxr; j++) {
for (i=1; i<=maxc; i++) {
printf( "%s\t", out[i,j]) # out field separator.
}
printf( "%s\n","" )
}
}' infile
そして素敵にしましょう(タブを\t
フィールドセパレータとして使用)。
./script | |column -t -s $'\t'
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U7 0004fb00000600003da8ce6948c441bd Running 65536 17103 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
上記の一般的なプリコードは、行列全体をメモリに格納します。
これは非常に大きなファイルの場合に問題になる可能性があります。
新しいテキストで更新してください。
質問に投稿された新しいテキストを処理するには、awk 2回が最良の答えだと思います。パスは、フィールドが存在する限りヘッダーフィールドのタイトルを出力します。次のawk転送では、フィールド2のみが印刷されます。どちらの場合も、先頭と末尾のスペースを削除する方法を追加しました(より良い書式設定のため)。
#!/bin/bash
{
awk -F: 'BEGIN{ sl="Virtual Machine"}
$1~sl && head == 1 { head=0; exit 0}
$1~sl && head == 0 { head=1; }
head == 1 {
gsub(/^[ \t]+/,"",$1); # remove leading spaces
gsub(/[ \t]+$/,"",$1); # remove trailing spaces
printf( "%s\t", $1)
}
' infile
#echo
awk -F: 'BEGIN { sl="Virtual Machine"}
$1~sl { printf( "%s\n", "") }
{
gsub(/^[ \t]+/,"",$2); # remove leading spaces
gsub(/[ \t]+$/,"",$2); # remove trailing spaces
printf( "%s\t", $2)
}
' infile
echo
} | column -t -s "$(printf '%b' '\t')"
すべてが{ ... } | column -t -s "$(printf '%b' '\t')"
テーブル全体の形式を良い方法で指定します。
これは"$(printf '%b' '\t')"
ksh、bash、またはzshに置き換えることができます。$'\t'
答え4
awkを使用してキーと値を保存し、最終的に印刷します。
#!/usr/bin/awk -f
BEGIN {
CNT=0
FS=":"
}
{
HDR[CNT]=$1;
ENTRY[CNT]=$2;
CNT++;
}
END {
for (x = 0; x < CNT; x++)
printf "%s\t",HDR[x]
print""
for (x = 0; x < CNT; x++)
printf "%s\t",ENTRY[x]
}
ただ逃げたawk -f ./script.awk ./input.txt