GNU/Linux >> Belajar Linux >  >> Linux

Awk satu baris dan skrip untuk membantu Anda mengurutkan file teks

Awk adalah perintah Unix di mana-mana untuk memindai dan memproses teks yang berisi pola yang dapat diprediksi. Namun, karena memiliki fungsi, itu juga dibenarkan disebut bahasa pemrograman.

Yang membingungkan, ada lebih dari satu awk. (Atau, jika Anda yakin hanya ada satu, maka ada beberapa klon.) Ada awk , program asli yang ditulis oleh Aho, Weinberger, dan Kernighan, lalu ada nawk , mengerang , dan versi GNU, melotot . Versi GNU awk adalah versi utilitas perangkat lunak gratis yang sangat portabel dengan beberapa fitur unik, jadi artikel ini adalah tentang GNU awk.

Meskipun nama resminya adalah gawk, pada sistem GNU+Linux ia disebut awk dan berfungsi sebagai versi default dari perintah tersebut. Pada sistem lain yang tidak dikirimkan dengan GNU awk, Anda harus menginstalnya dan menyebutnya sebagai gawk, bukan awk. Artikel ini menggunakan istilah awk dan melongo secara bergantian.

Menjadi perintah dan bahasa pemrograman membuat awk alat yang ampuh untuk tugas-tugas yang mungkin dibiarkan mengurutkan , potong , unik , dan utilitas umum lainnya. Untungnya, ada banyak ruang di open source untuk redundansi, jadi jika Anda dihadapkan pada pertanyaan apakah akan menggunakan awk atau tidak, jawabannya mungkin adalah "mungkin".

Keindahan dari fleksibilitas awk adalah jika Anda sudah berkomitmen untuk menggunakan awk untuk suatu tugas, maka Anda mungkin dapat tetap menggunakan awk tidak peduli apa yang muncul di sepanjang jalan. Ini termasuk kebutuhan abadi untuk menyortir data dengan cara selain dari urutan pengirimannya kepada Anda.

Kumpulan sampel

Sebelum menjelajahi metode pengurutan awk, buat kumpulan data sampel untuk digunakan. Tetap sederhana sehingga Anda tidak terganggu oleh kasus tepi dan kerumitan yang tidak diinginkan. Ini adalah kumpulan sampel yang digunakan artikel ini:

Aptenodytes;forsteri;Miller,JF;1778;Emperor
Pygoscelis;papua;Wagler;1832;Gentoo
Eudyptula;minor;Bonaparte;1867;Little Blue
Spheniscus;demersus;Brisson;1760;African
Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
Torvaldis;linux;Ewing,L;1996;Tux

Ini adalah kumpulan data kecil, tetapi menawarkan variasi tipe data yang baik:

  • Nama genus dan spesies, yang terkait satu sama lain tetapi dianggap terpisah
  • Nama keluarga, terkadang dengan inisial pertama setelah koma
  • Bilangan bulat yang mewakili tanggal
  • Istilah sewenang-wenang
  • Semua kolom dipisahkan dengan titik koma

Bergantung pada latar belakang pendidikan Anda, Anda dapat menganggap ini sebagai larik 2D atau tabel atau hanya kumpulan data yang dibatasi garis. Bagaimana Anda memikirkannya terserah Anda, karena awk tidak mengharapkan apa pun selain teks. Terserah Anda untuk memberi tahu awk bagaimana Anda ingin menguraikannya.

Cheat sortir

Jika Anda hanya ingin mengurutkan kumpulan data teks menurut bidang tertentu yang dapat ditentukan (bayangkan "sel" dalam spreadsheet), Anda dapat menggunakan perintah sort.

Bidang dan catatan

Terlepas dari format input Anda, Anda harus menemukan pola di dalamnya sehingga Anda dapat fokus pada bagian data yang penting bagi Anda. Dalam contoh ini, data dibatasi oleh dua faktor:garis dan bidang. Setiap baris baru mewakili rekor baru , seperti yang mungkin Anda lihat di spreadsheet atau dump database. Dalam setiap baris, ada bidang yang berbeda (anggap mereka sebagai sel dalam spreadsheet) yang dipisahkan oleh titik koma (;).

Awk memproses satu record pada satu waktu, jadi saat Anda menyusun instruksi yang akan Anda berikan kepada awk, Anda dapat fokus hanya pada satu baris. Tetapkan apa yang ingin Anda lakukan dengan satu baris, lalu uji (baik secara mental atau dengan awk) di baris berikutnya dan beberapa baris lagi. Anda akan mendapatkan hipotesis yang bagus tentang apa yang harus dilakukan skrip awk Anda untuk menyediakan struktur data yang Anda inginkan.

Dalam hal ini, mudah untuk melihat bahwa setiap bidang dipisahkan oleh titik koma. Demi kesederhanaan, anggap Anda ingin mengurutkan daftar berdasarkan bidang pertama dari setiap baris.

Sebelum Anda dapat mengurutkan, Anda harus dapat memfokuskan awk hanya pada bidang pertama dari setiap baris, jadi itulah langkah pertama. Sintaks dari perintah awk di terminal adalah awk , diikuti dengan opsi yang relevan, diikuti dengan perintah awk Anda, dan diakhiri dengan file data yang ingin Anda proses.

$ awk --field-separator=";" '{print $1;}' penguins.list
Aptenodytes
Pygoscelis
Eudyptula
Spheniscus
Megadyptes
Eudyptes
Torvaldis

Karena pemisah bidang adalah karakter yang memiliki arti khusus untuk shell Bash, Anda harus menyertakan titik koma dalam tanda kutip atau mendahuluinya dengan garis miring terbalik. Perintah ini hanya berguna untuk membuktikan bahwa Anda dapat fokus pada bidang tertentu. Anda dapat mencoba perintah yang sama menggunakan nomor bidang lain untuk melihat konten "kolom" lain dari data Anda:

$ awk --field-separator=";" '{print $3;}' penguins.list
Miller,JF
Wagler
Bonaparte
Brisson
Milne-Edwards
Viellot
Ewing,L

Belum ada yang diurutkan, tetapi ini adalah dasar yang bagus.

Skrip

Awk lebih dari sekedar perintah; itu adalah bahasa pemrograman dengan indeks dan array dan fungsi. Itu penting karena itu berarti Anda dapat mengambil daftar bidang yang ingin Anda urutkan, menyimpan daftar dalam memori, memprosesnya, dan kemudian mencetak data yang dihasilkan. Untuk serangkaian tindakan kompleks seperti ini, lebih mudah untuk bekerja dalam file teks, jadi buat file baru bernama sorter.awk dan masukkan teks ini:

#!/usr/bin/awk -f 

BEGIN {
        FS=";";
}

Ini menetapkan file sebagai skrip awk yang mengeksekusi baris yang terdapat dalam file.

MULAI pernyataan adalah fungsi pengaturan khusus yang disediakan oleh awk untuk tugas-tugas yang perlu terjadi hanya sekali. Mendefinisikan variabel bawaan FS , yang merupakan singkatan dari pemisah bidang dan merupakan nilai yang sama yang Anda tetapkan dalam perintah awk Anda dengan --field-separator , hanya perlu terjadi sekali, sehingga disertakan dalam MULAI pernyataan.

Array dalam awk

Anda sudah tahu cara mengumpulkan nilai bidang tertentu dengan menggunakan $ notasi bersama dengan nomor bidang, tetapi dalam kasus ini, Anda harus menyimpannya dalam array daripada mencetaknya ke terminal. Ini dilakukan dengan array awk. Hal penting tentang array awk adalah bahwa ia berisi kunci dan nilai. Bayangkan sebuah array tentang artikel ini; akan terlihat seperti ini:author:"seth",title:"How to sort with awk",length:1200 . Elemen seperti penulis dan judul dan panjang adalah kunci, dengan konten berikut sebagai nilai.

Keuntungannya dalam konteks penyortiran adalah Anda dapat menetapkan bidang apa pun sebagai kunci dan catatan apa pun sebagai nilainya, lalu menggunakan fungsi awk bawaan asorti() (urutkan berdasarkan indeks) untuk mengurutkan berdasarkan kunci. Untuk saat ini, anggap saja Anda hanya ingin mengurutkan berdasarkan bidang kedua.

Pernyataan awk tidak didahului oleh kata kunci khusus MULAI atau AKHIR adalah loop yang terjadi pada setiap record. Ini adalah bagian dari skrip yang memindai data untuk mencari pola dan memprosesnya sesuai dengan itu. Setiap kali awk mengalihkan perhatiannya ke sebuah record, pernyataan di {} (kecuali didahului dengan MULAI atau AKHIR ) dieksekusi.

Untuk menambahkan kunci dan nilai ke array, buat variabel (dalam contoh skrip ini, saya menyebutnya ARRAY , yang tidak terlalu orisinal, tetapi sangat jelas) yang berisi larik, lalu berikan kunci dalam tanda kurung dan nilai dengan tanda sama dengan (= ).

{   # dump each field into an array
    ARRAY[$2] = $R;
}

Dalam pernyataan ini, isi kolom kedua ($2 ) digunakan sebagai istilah kunci, dan catatan saat ini ($R ) digunakan sebagai nilai.

Fungsi asorti()

Selain array, awk memiliki beberapa fungsi dasar yang dapat Anda gunakan sebagai solusi cepat dan mudah untuk tugas-tugas umum. Salah satu fungsi yang diperkenalkan di GNU awk, asorti() , menyediakan kemampuan untuk mengurutkan larik berdasarkan kunci (atau indeks ) atau nilai.

Anda hanya dapat mengurutkan larik setelah diisi, artinya tindakan ini tidak boleh terjadi dengan setiap catatan baru tetapi hanya tahap akhir skrip Anda. Untuk tujuan ini, awk menyediakan END special khusus kata kunci. Kebalikan dari MULAI , sebuah AKHIR pernyataan hanya terjadi sekali dan hanya setelah semua catatan dipindai.

Tambahkan ini ke skrip Anda:

END {
    asorti(ARRAY,SARRAY);
    # get length
    j = length(SARRAY);
   
    for (i = 1; i <= j; i++) {
        printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
    }
}

asorti() fungsi mengambil konten ARRAY , mengurutkannya menurut indeks, dan menempatkan hasilnya dalam larik baru bernama SARRAY (nama arbitrer yang saya temukan untuk artikel ini, artinya ARRAY Terurut ).

Selanjutnya, variabel j (nama arbitrer lain) diberikan hasil dari length() fungsi, yang menghitung jumlah item dalam SARRAY .

Terakhir, gunakan untuk loop untuk mengulangi setiap item dalam SARRAY menggunakan printf() berfungsi untuk mencetak setiap kunci, diikuti dengan nilai yang sesuai dari kunci tersebut di ARRAY .

Menjalankan skrip

Untuk menjalankan skrip awk Anda, buat agar dapat dieksekusi:

$ chmod +x sorter.awk

Lalu jalankan dengan penguin.list contoh data:

$ ./sorter.awk penguins.list 
antipodes Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
chrysocome Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
demersus Spheniscus;demersus;Brisson;1760;African
forsteri Aptenodytes;forsteri;Miller,JF;1778;Emperor
linux Torvaldis;linux;Ewing,L;1996;Tux
minor Eudyptula;minor;Bonaparte;1867;Little Blue
papua Pygoscelis;papua;Wagler;1832;Gentoo

Seperti yang Anda lihat, data diurutkan berdasarkan kolom kedua.

Ini sedikit membatasi. Akan lebih baik jika Anda memiliki fleksibilitas untuk memilih saat runtime bidang mana yang ingin Anda gunakan sebagai kunci pengurutan sehingga Anda dapat menggunakan skrip ini pada kumpulan data apa pun dan mendapatkan hasil yang berarti.

Menambahkan opsi perintah

Anda dapat menambahkan variabel perintah ke skrip awk dengan menggunakan nilai literal var dalam naskah Anda. Ubah skrip Anda sehingga klausa berulang Anda menggunakan var saat membuat larik Anda:

{ # dump each field into an array
    ARRAY[$var] = $R;
}

Coba jalankan skrip sehingga mengurutkan berdasarkan bidang ketiga dengan menggunakan -v var opsi saat Anda menjalankannya:

$ ./sorter.awk -v var=3 penguins.list 
Bonaparte Eudyptula;minor;Bonaparte;1867;Little Blue
Brisson Spheniscus;demersus;Brisson;1760;African
Ewing,L Torvaldis;linux;Ewing,L;1996;Tux
Miller,JF Aptenodytes;forsteri;Miller,JF;1778;Emperor
Milne-Edwards Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
Viellot Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
Wagler Pygoscelis;papua;Wagler;1832;Gentoo

Perbaikan

Artikel ini telah menunjukkan cara mengurutkan data dalam awk GNU murni. Skrip dapat ditingkatkan sehingga, jika berguna bagi Anda, luangkan waktu untuk meneliti fungsi awk di halaman manual gawk dan menyesuaikan skrip untuk hasil yang lebih baik.

Berikut skrip lengkapnya sejauh ini:

#!/usr/bin/awk -f
# GPLv3 appears here
# usage: ./sorter.awk -v var=NUM FILE

BEGIN { FS=";"; }

{ # dump each field into an array
    ARRAY[$var] = $R;
}

END {
    asorti(ARRAY,SARRAY);
    # get length
    j = length(SARRAY);
   
    for (i = 1; i <= j; i++) {
        printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
    }
}

Linux
  1. Cara Menggunakan Awk dan Ekspresi Reguler untuk Memfilter Teks atau String dalam File

  2. Cara Mengurutkan File di Linux menggunakan Perintah Sortir

  3. Cara menggunakan Perintah tshark Wireshark untuk Port Kustom dan File Teks

  1. Cara Menemukan Jumlah File dalam Direktori dan Subdirektori

  2. Cara Menggunakan Perintah Grep untuk Menemukan Teks di File

  3. 10 perintah dasar Linux yang perlu Anda ketahui

  1. Temukan Perintah di Linux (Temukan File dan Direktori)

  2. Perintah Biner Dan Mode Teks Md5sum?

  3. Perintah untuk membuat daftar semua file kecuali . (titik) dan .. (titik titik)