Cara mencetak dua kolom terakhir menggunakan awk

106

Yang saya inginkan hanyalah dua kolom terakhir yang dicetak.

kendaraan
sumber
6
Tidak begitu yakin mengapa ini memiliki 87 suara positif, itu pasti dapat ditingkatkan dengan contoh paling tidak.
Arj
Mungkin karena pertanyaan itu pada dasarnya sangat sederhana dan mudah dipahami tanpa contoh, yang jarang terjadi, tetapi dalam kasus ini tampaknya berhasil. Masalahnya di sini bukanlah kurangnya informasi menurut saya, tetapi lebih dari itu menunjukkan kurangnya penelitian independen.
DryLabRebel
Pertanyaan ini juga merupakan duplikat dari pertanyaan ini .
DryLabRebel
Apakah ini menjawab pertanyaan Anda? Cetak kolom / kolom kedua terakhir di awk
DryLabRebel

Jawaban:

194

Anda dapat menggunakan variabel NFyang diatur ke jumlah total bidang dalam catatan masukan:

awk '{print $(NF-1),"\t",$NF}' file

ini mengasumsikan bahwa Anda memiliki setidaknya 2 bidang.

codaddict
sumber
1
Anda memerlukan koma - karena kita menjadi pemilih hari ini: spasi menggabungkan bidang, koma memisahkan bidang dalam pernyataan cetak. Itu akan menggabungkan dua bidang
jim mcnamara
18
Sekarang Anda sedang mencetak "field-OFS-tab-OFS-field". Ini harus awk '{print $(NF-1) "\t" $NF}' fileatau awk '{print $(NF-1), $NF}' fileatau awk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file.
Dijeda sampai pemberitahuan lebih lanjut.
Hanya untuk menambah komentar sebelumnya, masalah dengan menggunakan '{print $x,"\t",$y}'adalah awk menafsirkan setiap variabel yang dipisahkan koma sebagai bidangnya sendiri, jadi hasilnya akan benar-benar field1<space><tab><space>field2, (karena akan menggunakan pemisah spasi putih secara default) sebagai lawan field1<tab>field2yang mungkin adalah apa Anda mengharapkan. menggunakan Output Field Separator (OFS) hampir selalu sesuai dengan keinginan Anda.
DryLabRebel
13
awk '{print $NF-1, $NF}'  inputfile

Catatan: ini hanya berfungsi jika setidaknya ada dua kolom. Pada catatan dengan satu kolom Anda akan mendapatkan palsu"-1 column1"

jim mcnamara
sumber
3
Coba dan lihat. Ini berhasil Solaris 9 awk & nawk. Alternatifnya adalah $ (NF-1)
jim mcnamara
1
@coaddict - Saya rasa Anda belum bekerja dengan implementasi awk yang berbeda. Perilaku lama yang canggung telah (mungkin secara keliru) diajukan. Saya tidak memiliki kesempatan untuk menguji - yang mungkin Anda maksudkan. Jadi saya tidak tahu pasti mengapa komentar Anda datang, abnormal. Linux awk di luar kotak biasanya melongo. Saya akan menguji dan memposting kembali. Sementara itu coba Soalris atau HPUX atau DGX atau apapun untuk melihat apa yang saya maksud dengan awk lama.
jim mcnamara
6
Anda mungkin tertipu dengan mengira itu berhasil karena Anda mencoba echo 1 2 3 | awk .... $NF-1ada ($NF) - 1di setiap awkimplementasi.
Stephane Chazelas
Kode sumber "One True Awk" memiliki lebih dari 40 konflik dalam yacctata bahasa, yang ironis mengingat apa singkatan dari A di awk. Versi berbeda dari awk mem-parsing hal secara berbeda? Kejutan besar!
Kaz
1
@THESorcerer, coba dengan echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'- atau masukan lainnya di mana kolom ke-2 terakhir tidak kurang dari kolom terakhir.
glenn jackman
6

@jim mcnamara: coba gunakan tanda kurung untuk sekitar NF, yaitu $(NF-1)dan $(NF)sebagai ganti $NF-1dan $NF(bekerja di Mac OS X 10.6.8 untuk FreeBSD awkdan gawk).

echo '
1 2
2 3
one
one two three
' | gawk '{if (NF >= 2) print $(NF-1), $(NF);}'

# output:
# 1 2
# 2 3
# two three
guzo
sumber
Kami sudah mempertimbangkan () sebelumnya. Saya pikir kami sedang mendiskusikan dari mana asal perilaku awk lama yang asli.
jim mcnamara
+1 untuk jawaban dengan eksplisit $(NF-1)- yang setidaknya lebih portabel daripada $NF-1; itu pasti kurang ambigu. $(NF)adalah berlebihan, meskipun - $NFakan berhasil. Menjaga terhadap baris dengan kurang dari 2 kolom juga bermanfaat, karena dengan baris satu kolom Anda akan mendapatkan nilai kolom pertama dua kali , dan dengan nol-kolom - yaitu, baris kosong - perintah awk akan gagal sama sekali, karena suatu percobaan untuk mengakses bidang dengan indeks -1.
mklement0
1

menggunakan gawk menunjukkan masalahnya:

 gawk '{ print $NF-1, $NF}' filename
1 2
2 3
-1 one
-1 three
# cat filename
1 2
2 3
one
one two three

Saya baru saja melongo pada Solaris 10 M4000: Jadi, gawk adalah cuplrit pada masalah $ NF-1 vs. $ (NF-1). Pertanyaan selanjutnya apa yang dikatakan POSIX? per:

http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html

Tidak ada arah dengan satu atau lain cara. Tidak baik. gawk menyiratkan pengurangan, awks lainnya menyiratkan jumlah bidang atau pengurangan. hmm.

jim mcnamara
sumber
1
2 baris pertama dari file masukan sampel Anda tidak membantu dalam bahwa mereka menghasilkan output yang sama dengan baik perilaku. Bisakah Anda memastikan kembali bahwa Solaris awk memang TIDAK berperilaku seperti melongo dalam kasus ini?
mklement0
Adapun tautan Anda ke spesifikasi awk: Argumen anekdot yang digunakan $(NF-1)adalah bahwa dua contoh penghitungan indeks bidang dalam spesifikasi menggunakan formulir itu: $(NF-1)dan $(NF+2). Lalu ada bagian "Ekspresi dalam awk", yang mencantumkan $exprsebagai memiliki prioritas [jauh] lebih tinggi daripada expr - expr. Karena NFekspresi itu sendiri, $NF-1harus mengevaluasi ($NF)-1. Bahkan JIKA, bagaimanapun, memang ada implementasi yang aneh di luar sana yang mengevaluasi $NF-1sebagai $(NF-1), pelajaran yang didapat di sini adalah bahwa menggunakan $(NF-1)adalah pilihan yang aman dan portabel.
mklement0
0

coba dengan ini

$ cat /tmp/topfs.txt
/dev/sda2      xfs        32G   10G   22G  32% /

awk print last column
$ cat /tmp/topfs.txt | awk '{print $NF}'

awk print before last column
$ cat /tmp/topfs.txt | awk '{print $(NF-1)}'
32%

awk - print last two columns
$ cat /tmp/topfs.txt | awk '{print $(NF-1), $NF}'
32% /
namasivayam.cse
sumber
0

Harap coba ini untuk memperhitungkan semua kemungkinan skenario:

awk '{print $(NF-1)"\t"$NF}'  file

atau

awk 'BEGIN{OFS="\t"}' file

atau

awk '{print $(NF-1), $NF} {print $(NF-1), $NF}' file
Marios Karamanis
sumber