
次のように、出力からメーカー名、ファームウェアバージョン、およびカードのステータスを抽出したいと思いますfcinfo hba-port
。
root-#> fcinfo HBA ポート HBAポートWWN:10000000c96a53c5 オペレーティングシステムデバイス名:/dev/cfg/c2 メーカー: Emulex ← モデル: LPe11000-M4 ファームウェアバージョン:2.82a4(Z3D2.82A4) ← FCode/BIOS バージョン: ブート: 5.02a1 Fcode: 1.50a9 所蔵番号:VM73059524 ドライバー名: emlxs ドライババージョン:2.60k(2011.03.24.16.45) タイプ: Nポート ステータス:オンライン ← サポート速度: 1Gb 2Gb 4Gb 現在の速度:4GB ノードWWN:20000000c96a53c5
次の方法を使用してこれら3つのフィールドを抽出しますawk
。
root-#> fcinfo hba-port | awk '/Manufacturer:/{m=$2}/Firmware Version:/{F=$3}/State/{print m, F, $2}'
Emulex 2.82a4 online
Emulex 2.82a4 online
Emulex 2.82a4 offline
Emulex 2.82a4 offline
Emulex 2.82a4 online
Emulex 2.82a4 online
たとえば、次のように、よりユーザーフレンドリーな形式で出力を表示したいと思います。
HBA_Manufacturer Firmware_Version State
--------------------------------------------
Emulex 2.82a4 online
Emulex 2.82a4 offline
Emulex 2.82a4 offline
...タイトルを追加してデータに合わせて並べ替えます。どうすればいいですか?
Solarisソリューションが必要です。 (Linuxに適用される多くのコマンドはSolarisには適用されません。)
答え1
次のコマンドを使用せずに、列をcolumn
内部で完全に整列させることができます。awk
# fcinfo hba-port | awk '
BEGIN{man[-1]="HBA_Manufacturer"
ver[-1]="Firmware_Version"
sta[-1]="State"
man[0]="----------------"
ver[0]="----------------"
sta[0]="-----"
i=1
}
/Manufacturer:/ {man[i]=$2}
/Firmware Version:/ {ver[i]=$3}
/State:/ {sta[i]=$2; i++}
END {
maxlen1 = maxlen2 = maxlen3 = 0
for (j=-1; j<i; j++) {
if (length(man[j]) > maxlen1) maxlen1 = length(man[j])
if (length(ver[j]) > maxlen2) maxlen2 = length(ver[j])
if (length(sta[j]) > maxlen3) maxlen3 = length(sta[j])
}
for (j=-1; j<i; j++) {
printf("%-*s %-*s %-*s\n", maxlen1, man[j],
maxlen2, ver[j],
maxlen3, sta[j])
}
}'
これは入力テキスト全体を読み取り、データ(タイトルを含む)をman
、ver
およびsta
(製造元、バージョン、および状態)配列に保存します。列ヘッダーは項目に配置され、ダッシュ[-1]
(ヘッダーとデータの間に行を形成する)は項目[0]
に配置されます。これは出力の最初の2行になります(下記参照)。実際のデータはで始まります[1]
。
データの終わりに達すると、各列(ヘッダーを含む)のデータ最大長を決定し、計算された列幅を使用して配列内のすべてのデータを印刷します。
printf("%16s", "Emulex")
印刷しますEmulex
(前に10個のスペース、その後に6文字の名前、合計16文字)。printf("%-16s", "Emulex")
(知っている-
)が印刷されますEmulex
(6桁の名前と10文字の末尾のスペース、合計16文字)。printf("%-*s", 16, "Emulex")
フォーマット文字列の代わりにパラメータprintf("%-16s", "Emulex")
リストから取得する以外は同じことを行います。16
したがって、上記は次のような出力を生成します。
HBA_Manufacturer Firmware_Version State ---------------- ---------------- ----- Emulex 2.82a4 online Emulex 2.82a4 online Emulex 2.82a4 offline Emulex 2.82a4 offline Emulex 2.82a4 online Emulex 2.82a4 online
列の間にさらにスペースが必要な場合は、フォーマット
printf
にスペースを追加してください。たとえば"%-*s %-*s %-*s\n"
、表示された出力例に近いものを提供します。表示される出力例には、タイトルの後に連続したダッシュラインがあります。上記のように、私のコマンドは各タイトルの下に小さなダッシュラインのみを提供します。一部のデータが長い場合、これはより明白になります。
HBA_Manufacturer Firmware_Version State ---------------- ---------------- ----- Emulex 2.82a4 online Emulex 2.82a4 online Some_other_manufacturer 2.82a4 offline Emulex 2.82a4 offline Emulex 2.82a4 online Emulex 2.82a4 online
必要に応じてこの問題を解決できます。
- 入力データが大きいと、
awk
すべてのデータを保存するスペースが不足する可能性があるため、この操作が失敗する可能性があります。 - 以前のバージョン
awk
(Solarisなど)を使用すると、構文エラーが原因で失敗する可能性があります。これが発生した場合は、printf
次のようにすべてのステートメントを1行に入力してください。printf("%-*s %-*s %-*s\n", maxlen1, man[j], maxlen2, ver[j], maxlen3, sta[j])
答え2
各列の希望の幅があらかじめ決められている場合awk
持つprintf
たとえば、20文字、15文字、10文字(間に2つのスペースを含む)の列が必要な場合は、Cと非常によく似ています。
(as in Q) /State/{printf "%-20s %-15s %-10s\n", m, F, $2}
(-
左揃えを提供します。デフォルトは右です。通常は数値には機能しますが、テキストには機能しません。)
幅をデータに合わせて調整するには、データを配列に保存し、必要な幅を計算し、アスタリスクでこれらの幅を使用できますprintf "%-*s ", len, data
。G-Manがこのcolumn
ショーに返信しました。これを行う方が簡単です。
答え3
次の手順で列を並べ替えることができます。
# fcinfo hba-port | awk '
BEGIN {printf("HBA_Manufacturer Firmware_Version State\n")
printf("---------------- ---------------- -----\n")
}
/Manufacturer:/ {m=$2}
/Firmware Version:/ {F=$3}
/State/ {print m, F, $2}' | column -t
これにより、次のような出力が生成されます。
HBA_Manufacturer Firmware_Version State
---------------- ---------------- -----
Emulex 2.82a4 online
Emulex 2.82a4 online
Emulex 2.82a4 offline
Emulex 2.82a4 offline
Emulex 2.82a4 online
Emulex 2.82a4 online
メモ:
- 列間にさらにスペースが必要な場合は、最後に(または)オプションを使用して列間に入れる文字列を指定します。デフォルトは2つのスペースです。たとえば、4つのスペースを使用すると、表示された出力例に近い結果が得られます。
--output-separator string
-o string
… | column -t -o " "
表示される出力例には、タイトルの後に連続したダッシュラインがあります。上記のように、私のコマンドは各タイトルの下に小さなダッシュラインのみを提供します。一部のデータが長い場合、これはより明白になります。
HBA_Manufacturer Firmware_Version State ---------------- ---------------- ----- Emulex 2.82a4 online Emulex 2.82a4 online Some_other_manufacturer 2.82a4 offline Emulex 2.82a4 offline Emulex 2.82a4 online Emulex 2.82a4 online
必要に応じてこの問題を解決できます。
答え4
試行錯誤を経てタブを調整する必要があるかもしれませんが、一般的に -
awk 'BEGIN{printf("HBA_Manufacturer\t\t\tFirmware_Version\t\t\tState\n----------------------------------------\n")} {... printf("%s\t\t\t%s\t\t\t%s\n", m, f,$2) }