[unix] 마지막 열만 인쇄하는 방법?

echo -e 'one two three\nfour five six\nseven eight nine'
one two three
four five six
seven eight nine

어떻게 “MAGIC”이이 출력을 얻을 수 있습니까? :

three
six
nine

업데이트 :이 특정 방식으로 필요하지 않습니다. 행에 몇 개의 열이 있든 관계없이 일반적인 솔루션이 필요합니다. 예 : awk는 항상 마지막 열을 표시합니다.



답변

그것도 단지와 함께 할 수 'bash'없는 'sed', 'awk'또는 'perl':

echo -e 'one two three\nfour five six\nseven eight nine' |
  while IFS=" " read -r -a line; do
    nb=${#line[@]}
    echo ${line[$((nb - 1))]}
  done


답변

시험:

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


답변

생각보다 쉽습니다.

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


답변

시도하십시오 grep(짧거나 간단하지만 awk정규식 사용으로 인해 3 배 느립니다 ).

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

파싱 ​​시간 통계를 수행했습니다 (MBP OS X에서 테스트 ~ ~ 3 배, 가장 낮음).

  • 사용하여 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

답변

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


답변

다음을 사용하여 수행 할 수도 있습니다 'sed'.

echo -e 'one two three\nfour five six\nseven eight nine' | sed -e 's/^.* \([^ ]*\)$/\1/'

최신 정보:

또는 더 간단하게 :

echo -e 'one two three\nfour five six\nseven eight nine' | sed -e 's/^.* //'


답변

또는 사용 cut:

echo -e 'one two three\nfour five six\nseven eight nine' | cut -f 3 -d' '

‘일반 솔루션’요구 사항을 충족하지는 않지만 rev두 번 사용하면 이 문제도 해결할 수 있습니다.

echo -e 'one two three\nfour five six\nseven eight nine' | rev | cut -f 1 -d' ' | rev