コマンド出力から2番目の列を抽出しようとしています。
たとえば、
$ sudo /usr/sbin/pvs
PV VG Fmt Attr PSize PFree
/dev/sdc1 vgswap lvm2 a-- 16.00g 0
/dev/sdc2 rootvg lvm2 a-- 48.00g 2.70g
/dev/sde lvm2 --- 32.00g 32.00g
/dev/sdf lvm2 --- 32.00g 32.00g
しかし、問題は、一部のディスクがVGに関連付けられていないため、出力の抽出中にVG名が空であることです。
$ sudo /usr/sbin/pvs | awk '{print $2}'
VG
vgswap
rootvg
lvm2
lvm2
このように抽出したいです(空の場合は空にしてください)
vgswap
rootvg
答え1
ユーザー専用のデフォルト形式ではなく、後処理用に設計された出力形式を使用します。
$ sudo pvs --reportformat json_std | jq -r '.report[].pv[].vg_name'
vgswap
rootvg
または、pvs
希望の形式で希望の値を取得するように依頼してください。
$ sudo pvs --no-headings --config 'log{prefix=""}' -o vg_name
vgswap
rootvg
ソートとインデントを無効にし、区切り文字を変更することで、デフォルトの出力形式を後処理するのが簡単になります。
sudo pvs --config $'report{aligned=0 separator="\t"}log{prefix=""}'
値に改行やタブが含まれていない限り、それを単純なTSVにし、次のように後処理できます。
列には常にヘッダーvg_name
があるとしますVG
。
mlr --tsvlite --headerless-csv-output cut -f VG
または:
awk 'NR==1{for (i = i; i <= NF; i++) h[$i]=i; next}
{print $ h["VG"]}'
あるいは、そのvg_name
列が常に2番目の列であると仮定します。
awk -F'\t' 'NR > 1 {print $2}'
出力形式を変更せずに、デバイス名に改行文字やその他の制御文字またはマルチバイト文字が含まれていないと仮定し、VG名にスペースを含めることができないという事実に基づいて、最初のVG
ヘッダー行で文字列のオフセットを変更できます。 。その後の行でその値を見つける場所を知るために記録されました。
sudo pvs | awk '
NR == 1 {offset = index($0, "VG"); next}
{$0 = substr($0, offset); sub(/ .*/, ""); print}'
答え2
awkを使用してください。
$ cat file | awk 'NR==1{n=NF; next} {print (NF<n ? "" : $2)}'
vgswap
rootvg
これは単に最初の行のフィールド数を出力するように設定しn
、そのフィールド数があれば$ 2を印刷し、それ以外の場合は行の残りの部分に空の文字列を印刷します。
GNU awkを使用することもできますFIELDWIDTHS
。固定幅フィールドあなたのコメントから:
$ cat file | awk -v FIELDWIDTHS='13 9 *' 'NR>1{print $2}'
vgswap
rootvg
システムのに置き換えてくださいcat file
。sudo /usr/sbin/pvs