Saya memiliki file data yang ingin dinormalisasi menggunakan awk
, berdasarkan datapoint terakhir. Untuk itu, saya ingin mengakses titik data terakhir terlebih dahulu, untuk menormalkan data, kemudian memproses secara normal.
Metode berikut, menggunakan tac
dua kali, melakukan pekerjaan, tetapi, mungkin lebih rumit daripada yang diperlukan.
$ cat file
0 5
1 2
2 3
3 4
$ tac file | awk 'NR==1{norm=$2} {print $1, $2/norm}' | tac
0 1.25
1 0.5
2 0.75
3 1
Pertanyaan saya adalah sebagai berikut: Apakah mungkin mendapatkan hasil di atas dengan menggunakan awk saja?
Saya pikir jawabannya adalah "Tidak, awk memindai file baris demi baris", tetapi saya terbuka untuk saran untuk alternatif.
sumber
$ awk --version GNU Awk 3.1.8
. Bisakah Anda menambahkan penjelasan yang sangat kecil tentang bagaimana dua file input ditangani dan apanext
fungsinya?Jika sumber data Anda adalah file yang dapat dibaca berkali-kali (artinya ini bukan stream), Anda harus terlebih dahulu menggunakan
tail(1)
untuk mendapatkan data yang Anda inginkan dari baris terakhir dan meneruskannya ke awk untuk pemrosesan berurutan file tersebut.tail
akan berusaha ke akhir file untuk membaca baris terakhir tanpa perlu membaca semua data sebelumnya.Ini akan menjadi kemenangan besar pada file besar di mana seluruh file tidak akan muat dalam buffer cache (artinya perlu dibaca dari disk dua kali, sekali untuk setiap pass), dan akan membantu pada tingkat yang lebih kecil dengan tidak perlu memindai input untuk sampai ke baris terakhir. File yang lebih kecil mungkin tidak menunjukkan banyak perbedaan pada pendekatan dua langkah.
sumber
Anda bisa memuatnya ke dalam array dan membacanya mundur:
Anda bisa melakukannya dengan lebih efisien, tetapi jenis ini menggambarkan mengapa
awk
bukan alat yang tepat untuk ini. Terus menggunakantac
jika tersedia, GNU tac umumnya yang tercepat dari berbagai alat untuk pekerjaan ini.sumber
for
-loopawk
bukanlah solusi.