次のコマンドを実行すると、以下のように列リストが出力されます。
# rancher clusters
CURRENT ID STATE NAME PROVIDER
* abcd active test-cluster Imported
efgh active prod-cluster Imported
xyzd active dev-cluster Imported
NAME列を印刷しようとすると、test-clusterは結果に返されません。
# rancher clusters | awk '{print $3}'
STATE
active
prod-cluster
dev-cluster
印刷されたNAME列に表示されているSTATE列の一部を表示できます。
4 番目の列を印刷すると、テストクラスターが NAME とともに返されます。
# rancher clusters | awk '{print $4}'
NAME
test-cluster
Imported
Imported
awkが印刷された正確な列の値を返さないのはなぜですか?ある列の値が別の列に返されるのはなぜですか?私の期待は、3ドルを印刷すると、4番目の列(名前)のすべての結果が得られることです。
答え1
あなたはいGet $3
- しかし、デフォルトでは、awkはレコードをフィールドに分割するときの先頭と末尾のスペースを無視します。
フィールド区切り文字を明示的に設定して、前のスペースを空のフィールドとして扱うように強制できる必要があります。
$ cat clusters | awk -F'[ \t]+' '{print $3}'
STATE
active
active
active
しかし、
$ cat clusters | awk '{print $3}'
STATE
active
prod-cluster
dev-cluster
答え2
awkは区切り文字に基づいて文字列を分割します(デフォルトは1つ以上のスペース、つまりタブまたはスペース)。より明確にするために、ここにあなたのデータがあります。データは以下で提供されます。|
CURRENT|ID|STATE|NAME|PROVIDER
*|abcd|active|test-cluster|Imported
efgh|active|prod-cluster|Imported
xyzd|active|dev-cluster|Imported
上記のように、最初の行は$1
is CURRENT
、$2
isID
などです。 2行目$1
はis *
、$2
isabcd
などです。ただし、3行目はID列に対応しています$1
。efgh
CURRENT列にはスペース以外には何もないため、awkはこれを無視して$3
3行と4行のNAMEを表示します。
あなたがしなければならないのは、最初の列をawkに送信する前に削除することだけです。次のコマンドを使用できます。
rancher clusters | cut -b 8- | awk '{ print $3 }'
cut
上記のパイプラインのコマンドは、各行の最初の7バイトを削除し、残りはSTDOUTに印刷します。これにより、awk
各行の列数が異なる場合でも混乱は発生しません。
答え3
デフォルトでは、awk は先行スペースと末尾のスペースを無視し、連続したスペースシーケンスに基づいてレコードをフィールドに区切ります。最初の「フィールド」は時々空であり、awkは存在しません。これを考えると、NAME列を印刷する方法はいくつかあります。最も簡単な方法は、レコードの先頭ではなく最後からフィールド数を数えることです。
$ awk '{print $NF}' file
PROVIDER
Imported
Imported
Imported
$
$ awk '{print $(NF-1)}' file
NAME
test-cluster
prod-cluster
dev-cluster
$
$ awk '{print $(NF-2)}' file
STATE
active
active
active
$
$ awk '{print $(NF-3)}' file
ID
abcd
efgh
xyzd
$
$ awk '{print (NF>4 ? $(NF-4) : "")}' file
CURRENT
*
$
$(NF-4)
NFが4のときに印刷されないように、最後の項目に対していくつかの計算を実行する必要があります$0
。 4をハードコーディングする代わりに、ヘッダー行のフィールド数を数えることで予想されるフィールド数を計算できます。
$ awk 'NR==1{max=NF-1} {print (NF>max ? $(NF-max) : "")}' file
CURRENT
*
$
答え4
問題は、rancher
コマンド出力に1行に5つのフィールドがある場合もあり、4つのフィールドがある場合もあることです。
NF
次のawk 1行ステートメントは、指定された入力行のフィールド数に基づいて正しいフィールドを印刷します(awkの組み込み変数を使用)。
$ awk 'NF==5 {print $4}; NF==4 {print $3}' clusters.txt
NAME
test-cluster
prod-cluster
dev-cluster
または、空の行がないと確信している場合は、次のように使用できます。
$ awk '{print $(NF-1)}' clusters.txt
NAME
test-cluster
prod-cluster
dev-cluster
空行があると、次のエラーメッセージが表示されます。
awk: cmd. line:1: (FILENAME=clusters.txt FNR=5) fatal: attempt to access field -1
これは次の方法で回避できます。
awk 'NF>=1 {print $(NF-1)}' clusters.txt