Dalam Memperkenalkan ekspresi reguler , saya membahas apa itu dan mengapa mereka berguna. Sekarang, kita membutuhkan contoh dunia nyata untuk digunakan sebagai alat pembelajaran. Ini adalah salah satu yang saya temui beberapa tahun yang lalu.
Contoh ini menyoroti kekuatan dan fleksibilitas baris perintah Linux, terutama ekspresi reguler, karena kemampuannya untuk mengotomatiskan tugas-tugas umum. Saya telah mengelola beberapa listserv selama karir saya dan masih melakukannya. Orang-orang mengirimi saya alamat email untuk ditambahkan ke daftar itu. Dalam lebih dari satu kasus, saya telah menerima daftar nama dan alamat email dalam format Microsoft Word untuk ditambahkan ke salah satu daftar.
Daftar yang merepotkan
Daftar itu sendiri tidak terlalu panjang, tetapi formatnya tidak konsisten. Versi singkat dari daftar tersebut, dengan perubahan nama dan domain, ditampilkan di sini:
Team 1 Apr 3
Leader Virginia Jones vjones88@example.com
Frank Brown FBrown398@example.com
Cindy Williams cinwill@example.com
Marge smith msmith21@example.com
[Fred Mack] edd@example.com
Team 2 March 14
leader Alice Wonder Wonder1@example.com
John broth bros34@example.com
Ray Clarkson Ray.Clarks@example.com
Kim West kimwest@example.com
[JoAnne Blank] jblank@example.com
Team 3 Apr 1
Leader Steve Jones sjones23876@example.com
Bullwinkle Moose bmoose@example.com
Rocket Squirrel RJSquirrel@example.com
Julie Lisbon julielisbon234@example.com
[Mary Lastware) mary@example.com
Daftar asli memiliki baris tambahan, karakter seperti tanda kurung dan tanda kurung yang perlu dihapus, spasi putih seperti spasi dan tab, dan beberapa baris kosong. Format yang diperlukan untuk menambahkan email ini ke daftar adalah <first> <last> <email@example.com>
. Tugas kita adalah mengubah daftar ini menjadi format yang dapat digunakan oleh perangkat lunak milis.
Jelas bahwa saya perlu memanipulasi data untuk mengubahnya menjadi format yang dapat diterima untuk dimasukkan ke dalam daftar. Dimungkinkan untuk menggunakan editor teks atau pengolah kata seperti LibreOffice Writer untuk membuat perubahan yang diperlukan pada file kecil ini. Namun, orang-orang mengirimi saya file seperti ini cukup sering, jadi menggunakan pengolah kata untuk membuat perubahan ini menjadi tugas yang sulit. Terlepas dari kenyataan bahwa Writer memiliki fungsi pencarian dan penggantian yang baik, setiap karakter atau string harus diganti sendiri-sendiri, dan tidak ada cara untuk menyimpan pencarian sebelumnya.
Writer memang memiliki fitur makro yang kuat, tetapi saya tidak terbiasa dengan salah satu dari dua bahasanya:LibreOffice Basic atau Python. Saya tahu pemrograman shell Bash.
Saya melakukan apa yang terjadi secara alami pada sysadmin—saya mengotomatiskan tugas tersebut. Hal pertama yang saya lakukan adalah menyalin data alamat ke file teks sehingga saya dapat mengerjakannya menggunakan alat baris perintah. Setelah beberapa menit bekerja, saya mengembangkan program baris perintah Bash yang ditunjukkan di artikel sebelumnya:
$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/\]//g" -e "s/)//g" | awk '{print $1" "$2" <"$3">"}' > addresses.txt
Kode ini menghasilkan output yang diinginkan sebagai file addresses.txt
. Saya menggunakan pendekatan normal saya untuk menulis program baris perintah seperti ini dengan membangun pipeline satu perintah pada satu waktu.
Mari kita pecahkan pipa ini menjadi bagian-bagian komponennya untuk melihat cara kerjanya dan cocok satu sama lain. Semua eksperimen dalam seri ini harus dilakukan sebagai pengguna yang tidak memiliki hak istimewa. Saya juga melakukan ini pada VM yang saya buat untuk pengujian:studentvm1
.
File sampel
Pertama, kita perlu membuat file sampel. Buat direktori bernama testing
di komputer lokal Anda, lalu salin teks di bawah ke dalam file teks baru bernama Experiment_6-1.txt
, yang berisi tiga entri tim yang ditampilkan di atas.
Team 1 Apr 3
Leader Virginia Jones vjones88@example.com
Frank Brown FBrown398@example.com
Cindy Williams cinwill@example.com
Marge smith msmith21@example.com
[Fred Mack] edd@example.com
Team 2 March 14
leader Alice Wonder Wonder1@example.com
John broth bros34@example.com
Ray Clarkson Ray.Clarks@example.com
Kim West kimwest@example.com
[JoAnne Blank] jblank@example.com
Team 3 Apr 1
Leader Steve Jones sjones23876@example.com
Bullwinkle Moose bmoose@example.com
Rocket Squirrel RJSquirrel@example.com
Julie Lisbon julielisbon234@example.com
Menghapus baris yang tidak perlu dengan grep
Hal pertama yang saya lihat dapat dilakukan adalah beberapa hal yang mudah. Karena nama dan tanggal tim berada di baris tersendiri, kita dapat menggunakan yang berikut ini untuk menghapus baris yang memiliki kata "Tim:"
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team
Saya tidak akan mereproduksi hasil dari setiap tahap pembuatan program Bash ini, tetapi Anda harus dapat melihat perubahan dalam aliran data seperti yang muncul di STDOUT, sesi terminal. Kami tidak akan menyimpannya dalam file sampai akhir.
Pada langkah pertama dalam mengubah aliran data menjadi aliran yang dapat digunakan, kami menggunakan grep
perintah dengan pola literal sederhana, Team
. Literal adalah jenis pola paling dasar yang dapat kita gunakan sebagai ekspresi reguler, karena hanya ada satu kemungkinan kecocokan dalam aliran data yang dicari, dan itu adalah string Team
.
Kita perlu membuang baris kosong, jadi kita bisa menggunakan grep
lain pernyataan untuk menghilangkannya. Saya menemukan bahwa melampirkan ekspresi reguler untuk grep
second kedua perintah dalam tanda kutip memastikan bahwa itu ditafsirkan dengan benar:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader Virginia Jones vjones88@example.com
Frank Brown FBrown398@example.com
Cindy Williams cinwill@example.com
Marge smith msmith21@example.com
[Fred Mack] edd@example.com
leader Alice Wonder Wonder1@example.com
John broth bros34@example.com
Ray Clarkson Ray.Clarks@example.com
Kim West kimwest@example.com
[JoAnne Blank] jblank@example.com
Leader Steve Jones sjones23876@example.com
Bullwinkle Moose bmoose@example.com
Rocket Squirrel RJSquirrel@example.com
Julie Lisbon julielisbon234@example.com
[Mary Lastware) mary@example.com
[student@studentvm1 testing]$
Ekspresi "^\s*$"
mengilustrasikan jangkar, dan menggunakan garis miring terbalik (\) sebagai karakter pelarian untuk mengubah arti huruf "s" (dalam hal ini) menjadi metakarakter yang berarti spasi putih seperti spasi, tab, atau karakter lain yang tidak dapat dicetak. Kami tidak dapat melihat karakter-karakter ini di dalam file, tetapi ada beberapa di antaranya.
Tanda bintang, alias percikan (*), menentukan bahwa kita harus mencocokkan nol atau lebih karakter spasi putih. Penambahan ini akan cocok dengan beberapa tab, beberapa spasi, atau kombinasi apa pun dari yang ada di baris kosong.
Melihat spasi ekstra dengan Vim
Selanjutnya, saya mengonfigurasi editor Vim saya untuk menampilkan spasi menggunakan karakter yang terlihat. Lakukan ini dengan menambahkan baris berikut ke ~.vimrc
Anda sendiri file, atau ke /etc/vimrc
global file konfigurasi:
set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+
Kemudian, mulai—atau mulai ulang—Vim.
Saya telah menemukan banyak informasi yang buruk, tidak lengkap, dan kontradiktif di internet dalam pencarian saya tentang bagaimana melakukan ini. Bantuan Vim bawaan memiliki informasi terbaik, dan jalur data yang saya buat dari yang di atas adalah yang berfungsi untuk saya.
Catatan: Pada contoh di bawah, spasi reguler ditampilkan sebagai
+
; tab ditampilkan sebagai<
,<
, atau<–>
, dan isi panjang ruang yang dicakup tab. Karakter akhir baris (EOL) ditampilkan sebagai$
.
Hasilnya, sebelum operasi apa pun pada file, ditampilkan di sini:
Team+1<>Apr+3~$
Leader++Virginia+Jones++vjones88@example.com<-->$
Frank+Brown++FBrown398@example.com<---->$
Cindy+Williams++cinwill@example.com<--->$
Marge+smith+++msmith21@example.com~$
+[Fred+Mack]+++edd@example.com<>$
$
Team+2<>March+14$
leader++Alice+Wonder++Wonder1@example.com<----->$
John+broth++bros34@example.com<>$
Ray+Clarkson++Ray.Clarks@example.com<-->$
Kim+West++++kimwest@example.com>$
[JoAnne+Blank]++jblank@example.com<---->$
$
Team+3<>Apr+1~$
Leader++Steve+Jones++sjones23876@example.com<-->$
Bullwinkle+Moose+bmoose@example.com<--->$
Rocket+Squirrel+RJSquirrel@example.com<>$
Julie+Lisbon++julielisbon234@example.com<------>$
[Mary+Lastware)+mary@example.com$
Menghapus karakter yang tidak perlu dengan sed
Anda dapat melihat bahwa ada banyak karakter spasi putih yang perlu dihapus dari file kami. Kita juga perlu menghilangkan kata "pemimpin", yang muncul dua kali dan huruf besar sekali. Mari kita singkirkan "pemimpin" terlebih dahulu. Kali ini, kita akan menggunakan sed
(stream editor) untuk melakukan tugas ini dengan mengganti string baru—atau string null dalam kasus kami—untuk pola yang cocok.
Menambahkan sed -e "s/[Ll]eader//"
ke pipa melakukan ini:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"
Dalam sed
. ini perintah, -e
berarti bahwa ekspresi kutipan-tertutup adalah skrip yang menghasilkan hasil yang diinginkan. Dalam ekspresi, s
berarti bahwa ini adalah substitusi. Bentuk dasar dari substitusi adalah s/<regex>/<replacement string>/
, jadi /[Ll]eader/
adalah string pencarian kami.
Kumpulan [Ll]
cocok dengan L
atau l
, jadi [Ll]eader
cocok dengan leader
atau Leader
. Dalam hal ini, string pengganti adalah null karena terlihat seperti garis miring ganda tanpa karakter atau spasi di antara dua garis miring (//
).
Mari kita juga menyingkirkan beberapa karakter asing seperti []()
yang tidak akan dibutuhkan:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g"
Kami telah menambahkan empat ekspresi baru ke sed
penyataan. Masing-masing menghapus satu karakter. Yang pertama dari ekspresi tambahan ini sedikit berbeda, karena kurung siku kiri ([
) karakter dapat menandai awal set. Kita perlu keluar dari kurung kurawal untuk memastikan bahwa sed
menafsirkannya dengan benar sebagai karakter biasa dan bukan karakter khusus.
Membersihkan dengan awk
Kita bisa menggunakan sed
untuk menghapus spasi awal dari beberapa baris, tetapi awk
perintah dapat melakukan itu, menyusun ulang bidang jika perlu, dan menambahkan <
karakter di sekitar alamat email:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'
awk
utilitas sebenarnya adalah bahasa pemrograman yang kuat yang dapat menerima aliran data pada STDIN-nya. Fakta ini membuatnya sangat berguna dalam program dan skrip baris perintah.
awk
utilitas bekerja pada bidang data, dan pemisah bidang default adalah spasi—ruang putih berapa pun. Aliran data yang telah kita buat sejauh ini memiliki tiga bidang yang dipisahkan oleh spasi (<first>
, <last>
, dan <email>
):
awk '{print $1" "$2" <"$3">"}'
Program kecil ini mengambil masing-masing dari tiga bidang ($1
, $2
, dan $3
) dan mengekstraknya tanpa spasi putih di depan atau di belakang. Kemudian mencetaknya secara berurutan, menambahkan satu spasi di antara masing-masing serta <>
karakter yang diperlukan untuk menyertakan alamat email.
Menutup
Langkah terakhir di sini adalah mengarahkan aliran data keluaran ke file, tetapi itu sepele, jadi saya serahkan kepada Anda untuk melakukan langkah itu. Anda sebenarnya tidak perlu melakukannya.
Saya menyimpan program Bash dalam file yang dapat dieksekusi, dan sekarang saya dapat menjalankan program ini kapan saja saya menerima daftar baru. Beberapa dari daftar itu cukup pendek, seperti yang ada dalam contoh ini. Lainnya cukup panjang, terkadang berisi hingga beberapa ratus alamat dan banyak baris "barang" yang tidak berisi alamat untuk ditambahkan ke daftar.
Catatan: Artikel ini adalah versi Bab 6 yang sedikit dimodifikasi dari Volume 2 buku Linux saya, Using and Administering Linux:Zero to SysAdmin, yang akan dirilis dari Apress pada akhir 2019.