最後の列だけを印刷する方法は?

最後の列だけを印刷する方法は?
echo -e 'one two three\nfour five six\nseven eight nine'
one two three
four five six
seven eight nine

この出力を得るためにどのように「魔法」を使用できますか? :

three
six
nine

更新:この特定の方法は必要ありません。行にいくつの列があっても、一般的な解決策が必要です。例: awk は常に最後の列を表示します。

答え1

努力する:

echo -e 'one two three\nfour five six\nseven eight nine' | awk '{print $NF}'

答え2

思ったより簡単です。

$ echo one two three | awk '{print $NF}'
three

答え3

試してみてください(もっと短くて簡単ですが、regexを使用してgrep3倍遅い)。awk

grep -o '\S\+$' <(echo -e '... seven eight nine')

またはex(より遅いですが、完了するとバッファ全体を印刷するため、所定の位置でソートまたは編集する必要がある場合に便利です):

ex -s +'%s/^.*\s//g' -c'%p|q!' <(echo -e '... seven eight nine')
ex +'%norm $Bd0' -sc'%p|q!' infile

所定の位置に切り替えるには、に-sc'%p|q!'置き換えます-scwq

またはbash:

while read line; do arr=($line); echo ${arr[-1]}; done < someinput

パフォーマンス

次のように1GBのファイルを生成します。

$ hexdump -C /dev/urandom | rev | head -c1G | pv > datafile

解析時間統計を実行しました(約3回実行してMBP OS Xでテストして最も低い値を得ました)。

  • 使用awk:

    $ time awk '{print $NF}' datafile > /dev/null
    real    0m12.124s
    user    0m10.704s
    sys 0m0.709s
    
  • 使用grep:

    $ time grep -o '\S\+$' datafile > /dev/null
    real    0m36.731s
    user    0m36.244s
    sys 0m0.401s
    
    $ time grep -o '\S*$' datafile > /dev/null
    real    0m40.865s
    user    0m39.756s
    sys 0m0.415s
    
  • 使用perl:

    $ time perl -lane 'print $F[-1]' datafile > /dev/null
    real    0m48.292s
    user    0m47.601s
    sys 0m0.396s
    
  • rev+を使用してくださいcut

    $ time (rev|cut -d' ' -f1|rev) < datafile > /dev/null
    $ time rev datafile | cut -d' ' -f1 | rev > /dev/null
    real    1m10.342s
    user    1m19.940s
    sys 0m1.263s
    
  • 使用ex:

    $ time ex +'%norm $Bd0_' -sc'%p|q!' datafile > /dev/null
    real    3m47.332s
    user    3m42.037s
    sys 0m2.617s
    $ time ex +'%norm $Bd0' -sc'%p|q!' datafile > /dev/null
    real    4m1.527s
    user    3m44.219s
    sys 0m6.164s
    $ time ex +'%s/^.*\s//g' -sc'%p|q!' datafile > /dev/null
    real    4m16.717s
    user    4m5.334s
    sys 0m5.076s
    
  • 使用bash:

    $ time while read line; do arr=($line); echo ${arr[-1]}; done < datafile > /dev/null
    real    9m42.807s
    user    8m12.553s
    sys 1m1.955s
    

答え4

... | perl -lane 'print $F[-1]'

関連情報