GNU/Linux >> Belajar Linux >  >> Linux

Memulai dengan ekspresi reguler:Sebuah contoh

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  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

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 protected]> . 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  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

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  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[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~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

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.


Linux
  1. Memulai dengan Zsh

  2. Memulai dengan ls

  3. Memulai PostgreSQL di Linux

  1. Memulai Samba untuk interoperabilitas

  2. Memulai SSH di Linux

  3. Cara:Memulai dengan Ansible

  1. Memulai dengan GnuCash

  2. Memulai dengan Etcher.io

  3. Memulai dengan ekspresi reguler