Cetak kolom / kolom kedua terakhir dalam awk


164

Saya ingin mencetak kolom atau kolom terakhir kedua dalam awk. Jumlah bidang adalah variabel. Saya tahu bahwa saya harus bisa menggunakan $NFtetapi tidak yakin bagaimana itu bisa digunakan.

Dan ini sepertinya tidak berhasil:

awk ' { print ( $NF-- )  } '

10
NFadalah indeks bidang terakhir, $NFadalah nilai bidang terakhir
glenn jackman

itu masuk akal sekarang. Itulah mengapa dolar di luar kurung berfungsi kurasa
Brian G

Jawaban:


279
awk '{print $(NF-1)}'

Harus bekerja


2
Ini tidak bekerja untuk saya. Saya mendapatkan "title: 5: command not found: NF-1" di awk 3.1.8 di bawah Ubuntu.
Gurgeh

3
Saya akan menghindari pengurangan sebelum / sesudah untuk memastikan Anda tidak mengubah nilai $ NF
Gregory Patmore

Ini pecah jika Anda mencoba untuk mendapatkan bidang terakhir ketiga sepertiawk -F '.' '{print $(NF-2)}'
gies0r

3
@ Burgeh: Ini terjadi karena $(..)memanggil perintah dalam subkulit tergantung pada shell yang Anda gunakan. Anda dapat mengatasi ini dengan menggunakan $ (NF-1)alih-alih $(NF-1).
Mengaplikasikan

21

Tambahan kecil untuk jawaban yang diterima Chris Kannon: hanya mencetak jika sebenarnya ada kolom terakhir kedua.

(
echo       | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1     | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2   | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)

15

Ini paling sederhana:

 awk '{print $--NF}' 

Alasan yang asli $NF--tidak berfungsi adalah karena ekspresi dievaluasi sebelum pengurangan, sedangkan pengurangan awalan saya dilakukan sebelum evaluasi.


Sebagai mnemonik, perilaku ini sama dengan C / Java dll. int x = ++i int x = i++, Awalan berarti kenaikan pertama; postfix berarti kenaikan nanti (penugasan pertama).
Akhir pekan


4

Anda tidak jauh dari hasilnya! Ini melakukannya:

awk '{NF--; print $NF}' file

Ini mengurangi jumlah bidang dalam satu, sehingga $NFberisi yang kedua dari belakang.

Uji

Mari kita menghasilkan beberapa angka dan mencetaknya di grup 5:

$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12

Mari kita cetak kedua dari belakang di setiap baris:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11

3

Solusi Perl mirip dengan solusi awk Chris Kannon:

perl -lane 'print $F[$#F-1]' file

Opsi baris perintah ini digunakan:

  • n lingkaran di sekitar setiap baris dari file input, jangan otomatis mencetak setiap baris

  • l menghapus baris baru sebelum diproses, dan menambahkannya kembali sesudahnya

  • amode autosplit - membagi jalur input ke dalam @Farray. Default untuk memisahkan di whitespace

  • e jalankan kode perl

The @Fautosplit Array dimulai pada index [0] sedangkan bidang awk mulai dengan $ 1.
$#Fadalah jumlah elemen dalam@F


1
atau gunakan pengindeksan negatif yang sudah disediakan oleh perl ...$F[-2]
Sundeep

2

Apakah Anda mencoba memulai dari kanan ke kiri dengan menggunakan perintah rev? Dalam hal ini Anda hanya perlu mencetak kolom ke-2:

seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11

1

Pertama-tama, kurangi nilainya dan kemudian cetak -

awk ' { print $(--NF)}' file

ATAU

rev file|cut -d ' ' -f2|rev

0

Jika Anda memiliki banyak kolom dan ingin mencetak semua tetapi tidak tiga kolom terakhir, maka ini mungkin membantu

awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.