Dengan Terminal: Menggunakan Ekspresi Reguler II: Penggantian

Dalam diriku artículo anterior Saya telah memberi tahu Anda pada tingkat dasar bagaimana masing-masing karakter khusus yang paling sering digunakan dari ekspresi reguler bekerja. Dengan ekspresi reguler ini dimungkinkan untuk melakukan pencarian kompleks dalam file teks atau dalam output dari perintah lain. Pada artikel ini saya akan menjelaskan cara menggunakan perintah sed untuk menemukan dan mengganti teks dengan cara yang jauh lebih efektif daripada hanya mengubah satu teks ke teks lainnya.

Sedikit lagi tentang perintah grep

Sebelum saya mulai berbicara tentang sed, saya ingin memberi komentar lebih banyak tentang perintah grep untuk sedikit melengkapi apa yang telah dijelaskan di artikel sebelumnya. Semua yang akan saya katakan akan relevan dengan yang ini juga. Nanti kita akan melihat hubungan antara ini dan pencarian.

Menggabungkan ekspresi reguler

Banyak karakter khusus yang telah saya bahas di artikel sebelumnya dapat digabungkan, tidak hanya dengan karakter lain, tetapi dengan ekspresi reguler keseluruhan. Cara melakukannya adalah dengan menggunakan tanda kurung untuk membentuk subekspresi. Mari kita lihat contohnya. Mari kita mulai dengan mengunduh teks yang dapat kita gunakan untuk pengujian. Ini adalah daftar frase. Untuk itu kita akan menggunakan perintah berikut:

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 Ini akan membuat Anda berada di direktori tempat Anda meluncurkan file dengan nama «frase». Anda dapat membukanya untuk melihatnya dan tertawa kecil. 🙂

Sekarang anggaplah kita ingin mencari frase yang memiliki tepat 6 kata. Kesulitannya adalah dalam membentuk ekspresi reguler yang cocok dengan setiap kata. Kata adalah urutan huruf, baik huruf besar atau kecil, yang akan menjadi seperti ini '[a-zA-Z]+', tetapi Anda juga harus menentukan bahwa huruf-huruf ini harus dipisahkan dengan karakter lain yang bukan huruf, artinya, akan seperti '[a-zA-Z]+[^a-zA-Z]+'. Ingat: "^" sebagai karakter pertama di dalam tanda kurung menunjukkan bahwa kami ingin mencocokkan dengan karakter yang tidak ada dalam rentang dan "+" menunjukkan 1 karakter atau lebih.

Kami sudah memiliki ekspresi reguler yang dapat cocok dengan sebuah kata. Untuk memasangkannya dengan 6, itu harus diulang 6 kali. Untuk itu kami menggunakan kuncinya, tetapi tidak ada gunanya meletakkannya '[a-zA-Z]+[^a-zA-Z]+{6}', karena 6 akan mengulangi bagian terakhir dari persamaan reguler dan yang kita inginkan adalah mengulang semuanya, jadi yang harus kita masukkan adalah ini: '([a-zA-Z]+[^a-zA-Z]+){6}'. Dengan tanda kurung kita membentuk subekspresi dan dengan tanda kurung kita mengulanginya 6 kali. Sekarang Anda hanya perlu menambahkan "^" di depan dan "$" di belakang untuk mencocokkan seluruh baris. Perintahnya adalah sebagai berikut:

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

Dan hasilnya adalah yang kami inginkan:

Ini lebih banyak dinyanyikan dari pada Macarena. Anda lebih selesai dari Luis Aguilé. Anda memiliki budaya yang lebih sedikit daripada batu. Anda tahu lebih banyak bahasa daripada Cañita Brava. Dia memiliki lebih banyak kerutan daripada Tutan Khamón. Anda tahu lebih sedikit dari Rambo tentang pengasuhan anak.

Perhatikan bahwa kita meletakkan parameter -E karena kita ingin menggunakan ekspresi reguler yang diperluas agar "+" berfungsi. Jika kita menggunakan yang dasar, kita harus melepaskan tanda kurung dan kurung kurawal.

Referensi belakang atau referensi latar

Jika Anda telah memasang pemeriksa ejaan, Anda mungkin akan memiliki daftar kata dalam /usr/share/dict/words. Jika tidak, Anda dapat menginstalnya di arch dengan:

sudo pacman -S words

Atau di debian dengan:

sudo aptitude install dictionaries-common

Jika mau, Anda dapat melihat file tersebut untuk melihat kata-kata apa yang dimilikinya. Ini sebenarnya adalah tautan ke file kata untuk bahasa distro Anda. Anda dapat menginstal beberapa file kata pada saat yang bersamaan.

Kami akan menggunakan file itu. Ternyata kami sangat penasaran untuk mengetahui semua palindrome tujuh huruf di luar sana. Bagi yang belum tahu: Palindrome adalah kata capicúa, artinya bisa dibaca dari kiri ke kanan serta dari kanan ke kiri. Mari coba perintah berikut:

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

Kelihatannya agak aneh, bukan? Jika kami mencobanya, hasilnya akan tergantung pada bahasa distro Anda dan kata-kata yang ada di daftar Anda, tetapi dalam kasus saya, dengan bahasa Spanyol, hasilnya adalah ini:

aniline aniline bergulir

Mari kita lihat cara kerja ekspresi reguler ini.

Terlepas dari "^" dan "$", yang sudah kita ketahui untuk apa, hal pertama yang kita lihat di sebelah kiri adalah tiga kelompok titik yang diapit tanda kurung. Jangan bingung dengan bilah di depan setiap tanda kurung. Mereka harus melepaskan tanda kurung karena kita menggunakan ekspresi reguler dasar, tetapi tidak memiliki arti lain. Yang penting adalah kita meminta tiga karakter dengan titik, tetapi masing-masing titik tersebut diapit tanda kurung. Ini untuk menyimpan karakter yang cocok dengan poin tersebut sehingga mereka dapat direferensikan lagi dari ekspresi reguler. Ini adalah penggunaan lain dari tanda kurung yang akan berguna nantinya dalam membuat penggantian.

Di sinilah ketiga angka di bawah ini datang dengan garis miring di depannya. Dalam hal ini, bilah itu penting. Ini digunakan untuk menunjukkan bahwa angka di bawah ini adalah referensi belakang dan merujuk ke salah satu tanda kurung sebelumnya. Misalnya: \ 1 mengacu pada tanda kurung pertama, \ 2 ke yang kedua, dan seterusnya.

Dengan kata lain, dengan ekspresi reguler yang telah kita masukkan, yang kita cari adalah semua kata yang dimulai dengan empat huruf apa pun dan kemudian memiliki huruf yang sama dengan huruf ketiga, yang lain sama dengan huruf kedua dan yang lain sama dengan yang pertama. Hasilnya adalah palindrom tujuh huruf yang ada di daftar kata. Seperti yang kita inginkan.

Jika kita menggunakan ekspresi reguler yang diperluas, kita tidak perlu keluar dari tanda kurung, tetapi dengan referensi latar ekspresi reguler yang diperluas tidak berfungsi di semua program karena tidak distandarisasi. Namun, dengan grep mereka berfungsi, jadi itu mungkin cara lain untuk melakukan hal yang sama. Anda bisa mencobanya jika mau.

Ekspresi pengganti: perintah sed

Selain menelusuri, salah satu kegunaan terbaik dari ekspresi reguler adalah mengganti teks yang kompleks. Untuk melakukan ini, salah satu cara untuk melakukannya adalah dengan perintah sed. Kekuatan perintah sed jauh melampaui penggantian teks, tetapi di sini saya akan menggunakannya untuk itu. Sintaks yang akan saya gunakan dengan perintah ini adalah sebagai berikut:

sed [-r] 's/REGEX/REPL/g' FICHERO

Atau juga:

COMANDO | sed [-r] 's/REGEX/REPL/g'

Dimana REGEX akan menjadi ekspresi reguler pencarian dan REPL akan menjadi penggantinya. Perlu diingat bahwa perintah ini tidak benar-benar menggantikan apa pun di file yang kami tunjukkan, tetapi yang dilakukannya adalah menunjukkan kepada kami hasil penggantian di terminal, jadi jangan takut dengan perintah yang akan saya masukkan selanjutnya. Tak satu pun dari mereka akan mengubah file apa pun di sistem Anda.

Mari kita mulai dengan contoh sederhana. Kita semua memiliki berbagai file konfigurasi di direktori / etc yang biasanya memiliki komentar yang diawali dengan "#". Misalkan kita ingin melihat salah satu file ini tanpa komentar. Misalnya, saya akan melakukannya dengan fstab. Anda dapat mencoba dengan yang Anda inginkan.

sed 's/#.*//g' /etc/fstab

Saya tidak akan meletakkan hasil perintah di sini karena itu tergantung pada apa yang Anda miliki di fstab Anda, tetapi jika Anda membandingkan output perintah dengan konten file, Anda akan melihat bahwa semua komentar telah hilang.

Dalam perintah ini ekspresi pencariannya adalah «#.*", Itu adalah" # "diikuti dengan sejumlah karakter, yaitu komentar. Dan ekspresi pengganti, jika Anda melihat pada dua batang berturut-turut, Anda akan melihat bahwa tidak ada satu pun, jadi yang dilakukannya adalah mengganti komentar dengan tidak ada apa pun, yaitu menghapusnya. Tidak mungkin lebih sederhana.

Sekarang kita akan melakukan yang sebaliknya. Misalkan yang kita inginkan adalah mengomentari semua baris file. Ayo coba seperti ini:

sed 's/^/# /g' /etc/fstab

Anda akan melihat bahwa, dalam keluaran perintah, semua baris dimulai dengan tanda pagar dan spasi kosong. Apa yang telah kita lakukan adalah mengganti awal baris dengan «# «. Ini juga merupakan contoh yang cukup sederhana dimana teks yang akan diganti selalu sama, tapi sekarang kita akan memperumitnya sedikit lagi.

Manfaat penggantian adalah bahwa dalam ekspresi pengganti Anda dapat menggunakan referensi latar seperti yang saya katakan sebelumnya. Mari kita kembali ke file frase yang kita unduh di awal artikel. Kami akan memasukkan semua huruf kapital yang ada di dalam tanda kurung, tetapi kami akan melakukannya dengan perintah:

sed 's/\([A-Z]\)/(\1)/g' frases

Apa yang kita miliki di sini adalah referensi belakang dalam ekspresi pengganti yang merujuk ke tanda kurung dalam ekspresi penelusuran. Tanda kurung dalam ekspresi pengganti adalah tanda kurung normal. Dalam ungkapan pengganti mereka tidak memiliki arti khusus, mereka ditempatkan apa adanya. Hasilnya adalah bahwa semua huruf kapital diganti dengan huruf yang sama, apapun itu, dengan tanda kurung di sekitarnya.

Ada karakter lain yang juga dapat digunakan dalam ekspresi pengganti, yaitu "&" dan diganti dengan semua teks yang cocok dengan ekspresi penelusuran. Contohnya adalah meletakkan semua frasa di file dalam tanda kutip. Ini dapat dicapai dengan perintah ini:

sed 's/.*/"&"/g' frases

Pengoperasian perintah ini sangat mirip dengan yang sebelumnya, hanya saja sekarang yang kita ganti adalah seluruh baris dengan baris yang sama dengan tanda kutip di sekitarnya. Karena kami menggunakan "&", tidak perlu memberi tanda kurung.

Beberapa perintah berguna dengan ekspresi reguler

Berikut adalah beberapa perintah yang menurut saya berguna atau membuat penasaran dan yang menggunakan ekspresi reguler. Dengan perintah ini utilitas ekspresi reguler jauh lebih baik daripada dengan contoh yang telah saya berikan sejauh ini, tetapi tampaknya penting bagi saya untuk menjelaskan sesuatu tentang cara kerja ekspresi reguler untuk memahaminya.

  • Tampilkan bagian dari halaman manual:

man bash | grep '^[A-Z][A-Z ]*$'

Tentu saja, Anda dapat mengubah perintah bash menjadi apa pun yang Anda inginkan. Dan kemudian dari man, Anda bisa langsung ke bagian yang Anda minati menggunakan, tentu saja, ekspresi reguler. Anda menekan «/» untuk mulai mencari dan menulis «^ALIASES$»Untuk pergi ke bagian ALIASES, misalnya. Saya pikir ini adalah penggunaan pertama yang saya mulai buat ekspresi reguler beberapa tahun yang lalu. Menelusuri beberapa halaman manual hampir tidak mungkin tanpa trik seperti ini.

  • Tunjukkan nama semua pengguna mesin termasuk yang khusus:

sed 's/\([^:]*\).*/\1/' /etc/passwd

  • Tampilkan nama pengguna, tetapi hanya yang memiliki shell:

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

Ini benar-benar dapat dilakukan dengan satu ekspresi reguler, tetapi cara melakukannya melampaui apa yang telah saya ceritakan di artikel ini, jadi saya melakukannya dengan menggabungkan dua perintah.

  • Masukkan koma sebelum tiga digit terakhir dari semua angka di file angka:

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

Ini hanya berfungsi dengan angka hingga 6 digit, tetapi dapat dipanggil lebih dari sekali untuk menempatkan pemisah di grup lain yang terdiri dari tiga digit.

  •  Ekstrak semua alamat email dari file:

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

  • Pisahkan hari, bulan dan tahun dari semua tanggal yang muncul di file:

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • Cari tahu IP lokal kami:

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

Ini juga dapat dilakukan dengan satu perintah sed, tetapi saya lebih baik memisahkannya menjadi grep dan sed untuk kesederhanaan.

Beberapa alamat yang berguna

Berikut beberapa alamat yang mungkin berguna terkait ekspresi reguler:

  • Perpustakaan ekspresi reguler: Ini adalah pustaka ekspresi reguler tempat Anda dapat mencari ekspresi reguler yang terkait dengan topik yang Anda minati. Untuk mencari alamat web, ID atau apapun.
  • RegExr: Pemeriksa ekspresi reguler online. Ini memungkinkan Anda untuk memasukkan teks dan menerapkan ekspresi reguler ke teks tersebut baik cari atau ganti. Ini memberikan informasi tentang ekspresi reguler dan Anda memiliki beberapa opsi untuk mengubah perilakunya.
  • Penguji Ekspresi Reguler: Ini adalah addon untuk firefox yang memungkinkan pemeriksaan ekspresi reguler dari browser.

Kesimpulan

Untuk sekarang itu saja. Ekspresi reguler itu rumit tetapi berguna. Perlu waktu untuk mempelajarinya, tetapi jika Anda seperti saya, bermain dengan mereka akan terasa menyenangkan dan, sedikit demi sedikit Anda akan menguasainya. Itu adalah dunia yang utuh. Masih banyak yang bisa dikatakan tentang lazy quantifiers, PERL-style regex, multiline, dll. Dan kemudian setiap program memiliki karakteristik dan variannya masing-masing, jadi saran terbaik yang dapat saya berikan kepada Anda adalah selalu melihat dokumentasi program yang Anda gunakan setiap kali Anda harus menulis ekspresi reguler di program baru.

Hei! …HEI! … BANGUN! … APA YANG ANDA SEMUA MELAKUKAN TIDUR? 🙂

Fuentes

Beberapa ide dan contoh ekspresi reguler dalam artikel ini saya ambil dari sini:


tinggalkan Komentar Anda

Alamat email Anda tidak akan dipublikasikan. Bidang yang harus diisi ditandai dengan *

*

*

  1. Penanggung jawab data: Miguel Ángel Gatón
  2. Tujuan data: Mengontrol SPAM, manajemen komentar.
  3. Legitimasi: Persetujuan Anda
  4. Komunikasi data: Data tidak akan dikomunikasikan kepada pihak ketiga kecuali dengan kewajiban hukum.
  5. Penyimpanan data: Basis data dihosting oleh Occentus Networks (UE)
  6. Hak: Anda dapat membatasi, memulihkan, dan menghapus informasi Anda kapan saja.

  1.   hidup dijo

    Mahir!!!

    1.    hexborg dijo

      Tidak terlalu buruk, tapi terima kasih banyak. Semoga orang menyukainya. 🙂

      1.    oscar dijo

        Saya suka itu ha!

        1.    hexborg dijo

          Maka saya pasti telah melakukan sesuatu dengan benar. LOL !! 🙂

          Terima kasih banyak atas komentar anda

          1.    Blaire pascal dijo

            Persetan terus menulis, teruskan.

          2.    hexborg dijo

            @ Blaire Pascal: Komentar seperti milik Anda mendorongnya. 🙂 Terima kasih banyak !!

      2.    citux dijo

        Saya juga menyukainya ... terima kasih 🙂

        1.    hexborg dijo

          Terima kasih atas komentarnya Saya berharap dapat menulis lebih banyak lagi. 🙂

  2.   Marian dijo

    Posting Anda luar biasa, Anda belajar banyak, sebaliknya, Anda belajar melakukan tugas dengan cara yang elegan dan efisien.

    Pernahkah Anda berpikir untuk mengumpulkan semua posting skrip shell Anda? Diurutkan ke dalam pdf akan menjadi manual yang bagus.

    Semangat dan terima kasih banyak!

    1.    hexborg dijo

      Terima kasih banyak!! Itu bukan ide yang buruk. Saat ini hanya ada dua, tapi saya akan memikirkannya nanti. 🙂

  3.   Kiyov dijo

    artikel yang sangat bagus, 5+.

    1.    hexborg dijo

      Terima kasih. Aku senang kau menyukainya. 🙂

  4.   sebastian dijo

    Luar biasa! Saya perlu mengubah ekspresi berikut dan saya tidak tahu bagaimana melakukannya:
    192.168.0.138/Server oleh 192.168.0.111/data
    Masalahnya terletak pada simbol "/".
    Saya menggunakan perintah:
    Temukan. -nama "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Apa yang digunakan untuk melakukan tugas jenis ini secara remisif, tapi saya tidak bisa ...
    Adakah yang tahu bagaimana saya harus melakukannya?
    Peluk!
    Seba

    1.    hexborg dijo

      Yang harus Anda lakukan adalah melarikan diri dari karakter seperti ini:

      Temukan. -name "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;

      Anda juga dapat menggunakan pemisah lain di sed. Tidak harus bar. Sed memungkinkan karakter apapun untuk digunakan. Misalnya, ini akan lebih jelas:

      Temukan. -name "* .txt" -exec sed -i 's | / Server | / data | g' {} \;

      Dan jika Anda akan menyalin dan menempelkan perintah dari komentar ini, hati-hati dengan tanda kutip, wordpress itu mengubahnya untuk tipografi. 🙂

      Salam.

  5.   sebastian dijo

    Bagus!
    Saya sudah lama mencari solusi ini.
    Disini saya tinggalkan perintah lengkap yang sudah saya gunakan

    Temukan. -nama "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    Keuntungan dari perintah ini adalah ia mengubah semua file .txt (atau ekstensi yang Anda inginkan) secara rekursif ... Anda harus sangat berhati-hati!
    Tapi itu sangat berguna !!!

    Terima kasih atas segalanya dan seribu selamat untuk seluruh grup.
    Saya selalu membacanya dari surat!
    Pelukan
    Seba