AWK - 最後の列を空の値とともに印刷する

AWK - 最後の列を空の値とともに印刷する

$NF最後の列番号がわからない場合は、を使用してファイル内の各行の最後の列を印刷できます。

しかし、最後の列に空の値があることが問題です。

例えば、解析whoコマンド

$ who
root     tty1         2018-01-25 09:36
root     pts/0        2018-05-30 07:39 (192.168.1.134)
root     pts/1        2018-05-28 23:12 (192.168.1.134)
root     pts/2        2018-06-01 10:01 (192.168.1.188)

結果を取得中:

$ who | awk '{print $NF}'
09:36
(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

期待される結果

(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

期待される結果をワンライナーで得る可能性を教えてください。

編集1:上記のシナリオは単なる例です。結果を得るために区切り文字を変更することは好みません。

編集2:最大値より少ないフィールドを持つ行からは何も出力されない(出力の空行)。

答え1

最大数の列を持つ行の最後の列のみを出力するには、次のようにします。

who | awk '
  NF > max  {max = NF; output = ""}
  NF == max {output = output $NF ORS}
  END       {printf "%s", output}'

入力の行ごとに 1 行を出力し、列の最大数に達していない行については空を出力するには、次のようにします。

who | awk '
  NF > max {max = NF}
  {n[NR] = NF}
  NF == max {last[NR] = $NF}
  END {for (i = 1; i <= NR; i++) print n[i] == max ? last[i] : ""}'

答え2

最も多くのフィールドを持つ行の最後のフィールドだけが必要な場合は、データを 2 回読み取る必要があります。1 回目は最も多くのフィールドを見つけるため、もう 1 回目はフィールドを印刷するためです。1 回だけ読み取るだけでは不十分です。どの行にも前の行よりも多くのフィールドがある可能性があり、それを知る方法はありません。

awk(ファイル名が 2 回指定されていることに注意してください) :

awk -vfields=0 'FNR==NR {if (NF > fields) fields=NF; next} 
     NF >= fields { print $NF } NF < fields {print ""}' file file

file含まれる場合

foo bar
one two three four
1 2 3
a b c d

これは 4 番目のフィールドを出力します。4 番目のフィールドがない行の場合は空になります。



d

もちろん、これはパイプでは機能しないので、一時ファイルを使用する必要があります。

別の解決策としては、印刷するフィールドを、より多くのフィールドを持つ行が現れるまでキャッシュしておくという方法があります。ステファンの答え

答え3

5 番目のフィールドが一致するかどうかを確認し\(.*\)、一致する場合はそれを出力します。

who | awk '$5 ~ /\(.*\)/{print $5}'

住所のみに興味がある場合はip、正規表現を変更します。

who |  awk '$5 ~ /\((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\)/{print $5}'

答え4

この列が利用可能な場合に最後の列のみを取得したい場合は、しない必要なのは 4 つの列だけです。

who | awk 'NF > 4 { print $NF }'

または、同様のデータを取得するには、

w -hi | awk '{ print $3 }'

関連情報