Agar Awk Hanya Menampilkan Kecocokan Pertama yang Ditemukannya

Judul apa pula ini...
Ya ya ya, efficient title is hard. Jadi izinkan saya untuk sedikit berpanjang lebar menyampaikan maksud dari judul yang aneh ini.

Alkisah, seringkali ketika berkelana di dunia maya dan menemukan artikel yang menarik atau dirasa berguna, maka saya kemudian menyimpannya agar bisa dibaca di kemudian waktu. Because you know, internet is unreliable.
Seperti yang sebelumnya telah sekilas disinggung dalam artikel Mari Hijrah ke Firefox Quantum, addons Mozilla Archive Format, with MHT and Faithful Save (MAF) yang biasanya saya gunakan untuk menyimpan laman web tidak bisa lagi digunakan di Firefox teranyar.

Lalu apa masalahnya? Nyimpen halaman kan bisa pake fitur bawaan Firefox?
Masalahnya adalah saya telah banyak memiliki berkas MHT hasil penyimpanan MAF, dan berkas ini kini tidak bisa dibuka menggunakan Firefox teranyar, mesti menggunakan Firefox lama atau peramban lain misalnya Opera. MAF sendiri memiliki fitur untuk mengekspor berkas MHT menjadi HTML, namun hasilnya kurang memuaskan.

Jadi ya, sambil menunggu siapa tahu Firefox kembali mendukung berkas MHT atau ada addons yang memungkinkan membaca berkas MHT, terlintas dalam benak ini untuk kembali mengunduh berkas tersebut satu per satu.

Langkah pertama tentunya mesti mencari tahu berkas MHT tersebut saya simpan dari alamat mana. Terbayang merepotkan; membuka berkas MHT tersebut satu per satu dan menyalin alamat asalnya. Namun beruntung, rupanya berkas MHT ini hanyalah berkas teks biasa dan bisa dibuka menggunakan piranti pengolah teks. Pastinya grep, awk atau sed bisa membantu.

Nah, sampai di sini mulai tampak benang merah dengan judul.
Jadi setelah berkas MHT tersebut dibuka menggunakan geany, penyunting teks andalan, saya menemukan sebuah baris yang menunjukkan alamat asal laman yang disimpan dalam berkas tersebut. Baris tersebut berbentuk seperti berikut:

Content-Location: http://www.reddit.com/r/AskReddit/comments/265gil/reddit_can_you_blow_my_mind_in_one_sentence/?limit=500

Tampaknya grep akan mudah saja mendapatkan laman tersebut.

grep -hm 1 *.mht

Hmmm, ternyata hasilnya tidak benar-benar hanya berupa tautan, namun masih mengandung string yang tidak diperlukan.

Content-Location: https://unnikked.ga/a-telegram-channel-and-group-scheduler-out-of-google-calendar-ifttt-and-hook-io-93a1716417db
Content-Location: http://web.neurotiko.com/bots/2015/08/03/bots-know-your-api/
Content-Location: https://core.telegram.org/bots
Content-Location: https://www.codementor.io/garethdwyer/tutorials/building-a-telegram-bot-using-python-part-1-goi5fncay
Content-Location: https://www.codementor.io/garethdwyer/tutorials/building-a-chatbot-using-telegram-and-python-part-2-sqlite-databse-backend-m7o96jger
Content-Location: https://unnikked.ga/exploring-telegram-bot-api-for-groups-cc476bdcea4c
Content-Location: http://web.neurotiko.com/bots/2015/07/21/bots-introduction/
Content-Location: https://unnikked.ga/getting-started-with-telegram-bots-9e467d922d69
Content-Location: https://unnikked.ga/handling-multimedia-files-via-telegram-bots-api-abe3ed450c69
Content-Location: https://unnikked.ga/how-i-coded-a-telegram-bot-that-evaluates-lisp-code-8b2970897b52
Content-Location: https://unnikked.ga/how-to-create-your-custom-telegram-bot-using-the-long-polling-technique-c8e925ccb1c6
Content-Location: https://unnikked.ga/how-to-easily-build-a-telegram-bot-with-hook-io-4c144c4abd96
Content-Location: https://unnikked.ga/how-to-manage-your-telegram-channel-with-your-unique-bot-554a8c90f7b5
Content-Location: https://blog.srnd.org/intro-to-node-js-making-a-telegram-bot-964b8cfe1129#.yngctmjdz
Content-Location: http://www.ft.com/cms/s/0/21c5c7f2-20b1-11e5-ab0f-6bb9974f25d0.html
Content-Location: http://web.neurotiko.com/bots/2015/08/09/bots-coding-simple-bot/
Content-Location: https://unnikked.ga/the-ultimate-guide-to-schedule-contents-on-your-telegram-channel-9cc25b922cd
Content-Location: https://unnikked.ga/tips-to-host-a-telegram-bot-d6cc9946e9e
Content-Location: https://unnikked.ga/understanding-telegram-inline-bots-73ac9aeea643
Content-Location: https://unnikked.ga/getting-started-with-telegram-bots

Seperti tampak pada hasil grep di atas, tautan terletak pada kolom kedua dan saya tidak bisa menemukan cara agar grep hanya menampilkan kolom berisi tautan itu saja. Cara yang saya ketahui adalah dengan piping hasil grep ke perkakas lain macam awk, cut dan lainnya.
Tampaknya untuk urusan kolom, awk-lah jagonya. Jadi, coba kita gunakan perintah awk berikut.

awk '/^Content-Location: /{print $2;exit}'

Wow.... Ternyata dalam berkas-berkas MHT tersebut mengandung banyak baris yang diawali string Content-Location:, jadinya awk menampilkan banyak sekali hasil sampah.
Bagaimana caranya agar awk hanya menampilkan hasil temuannya yang pertama saja dan mengabaikan temuan lain dalam berkas?
Nah, itulah maksud dari judul artikel ini 😂

Kali ini pun saya tidak menemukan cara yang singkat, namun setidaknya bisa hanya menggunakan awk semata, tanpa perlu bantuan utility lain.
Berikut kode akhirnya:

while IFS= read -r alamat; do 
  awk '/^Content-Location: /{print $2;exit}' "$alamat"
done < <(find . -type f -iname "*.mht") > daftar_tautan.txt

Penjelasan dari skrip tersebut adalah sebagai berikut;

  • <(find . -type f -iname "*.mht") artinya jalankan perintah find untuk mencari berkas yang mengandung ".mht" di akhir namanya. Tanda < di kiri perintah find mengartikan bahwa hasil pencarian find akan diberikan ke while loop.
  • while loop akan mengurut tiap baris dari hasil pencarian find dan menyimpannya ke dalam variabel alamat. Keterangan lebih rinci mengenai IFS dan -r bisa dibaca di Stack Overflow.
  • awk kemudian akan membaca alamat dan mengambil kolom kedua dari baris yang mengandung string Content-Location: pada bagian depannya. Perintah exit akan menghentikan awk agar menghentikan pencarian di alamat.
  • Setelah semua baris dibaca dan diolah, hasilnya kemudian akan disimpan ke dalam berkas daftar_tautan.txt. Berkas ini kemudian bisa diumpankan ke perkakas pengunduh seperti wget dan lainnya.

Demikianlah bagaimana saya menggunakan awk untuk mendapatkan kolom kedua dari baris pertama yang ditemukannya. Saya sendiri mengakui proses ini merepotkan dan bisa dihindari, namun setidaknya karena rela berepot-ria menggunakan awk, saya jadi belajar mengenai while loop dan multi redirection. Cukup sepadan lah...
Sementara soal mengunduh ulang artikelnya, nanti saja jika sudah berlimpah kuota...

Ciao...