Cara Menggunakan Perintah sed di Linux

Ini mungkin terdengar gila, tetapi sedperintah Linux adalah editor teks tanpa antarmuka. Anda dapat menggunakannya dari baris perintah untuk memanipulasi teks dalam file dan aliran. Kami akan menunjukkan cara memanfaatkan kekuatannya.

Kekuatan sed

The sedperintah adalah sedikit seperti catur: dibutuhkan satu jam untuk mempelajari dasar-dasar dan seumur hidup untuk menguasai mereka (atau, setidaknya banyak latihan). Kami akan menunjukkan kepada Anda pilihan langkah awal di setiap kategori sedfungsi utama .

sedadalah editor aliran yang bekerja pada input atau file teks yang disalurkan. Namun, itu tidak memiliki antarmuka editor teks interaktif. Sebaliknya, Anda memberikan instruksi untuk diikuti saat bekerja melalui teks. Ini semua berfungsi di Bash dan shell baris perintah lainnya.

Dengan sedAnda, Anda dapat melakukan semua hal berikut:

  • Pilih teks
  • Teks pengganti
  • Tambahkan baris ke teks
  • Hapus baris dari teks
  • Ubah (atau pertahankan) file asli

Kami telah menyusun contoh kami untuk memperkenalkan dan mendemonstrasikan konsep, bukan untuk menghasilkan perintah tersest (dan paling tidak dapat didekati) sed. Namun, fungsi pencocokan pola dan pemilihan teks sed sangat bergantung pada ekspresi reguler (ekspresi reguler). Anda akan membutuhkan pengetahuan tentang ini untuk mendapatkan yang terbaik sed.

TERKAIT: Cara Menggunakan Ekspresi Reguler (regex) di Linux

Contoh Sederhana

Pertama, kita akan menggunakan echountuk mengirim beberapa teks ke sedmelalui pipa, dan sed mengganti sebagian teks. Untuk melakukannya, kami mengetik yang berikut:

echo howtogonk | sed 's / gonk / geek /'

The echoperintah mengirimkan “howtogonk” ke sed, dan aturan substitusi kami sederhana (yang “s” singkatan substitusi) diterapkan. sed mencari teks masukan untuk kemunculan string pertama, dan akan mengganti setiap kecocokan dengan yang kedua.

String "gonk" diganti dengan "geek", dan string baru dicetak di jendela terminal.

Substitusi mungkin adalah penggunaan yang paling umum sed. Namun, sebelum kita bisa mendalami substitusi, kita perlu tahu cara memilih dan mencocokkan teks.

Memilih Teks

Kami akan membutuhkan file teks untuk contoh kami. Kami akan menggunakan salah satu yang berisi pilihan ayat dari puisi epik Samuel Taylor Coleridge "The Rime of the Ancient Mariner."

Kami mengetik yang berikut untuk melihatnya dengan less:

kurangi coleridge.txt

Untuk memilih beberapa baris dari file, kami menyediakan garis awal dan akhir dari rentang yang ingin kami pilih. Satu nomor memilih satu baris itu.

Untuk mengekstrak baris satu hingga empat, kita ketik perintah ini:

sed -n '1,4p' coleridge.txt

Perhatikan koma antara 1dan 4. The pberarti “mencetak garis cocok.” Secara default,  sed mencetak semua baris. Kami akan melihat semua teks dalam file dengan garis yang cocok dicetak dua kali. Untuk mencegahnya, kami akan menggunakan opsi -n(diam) untuk menyembunyikan teks yang tidak cocok.

Kami mengubah nomor baris sehingga kami dapat memilih ayat yang berbeda, seperti yang ditunjukkan di bawah ini:

sed -n '6,9p' coleridge.txt

Kita bisa menggunakan opsi -e(ekspresi) untuk membuat banyak pilihan. Dengan dua ekspresi, kita dapat memilih dua ayat, seperti:

sed -n -e '1,4p' -e '31, 34p 'coleridge.txt

Jika kita mengurangi angka pertama pada ekspresi kedua, kita bisa menyisipkan kosong di antara dua ayat. Kami mengetik berikut ini:

sed -n -e '1,4p' -e '30, 34p 'coleridge.txt

Kita juga dapat memilih garis awal dan memerintahkan sed untuk menelusuri file dan mencetak garis alternatif, setiap baris kelima, atau melewati sejumlah baris. Perintahnya mirip dengan yang kami gunakan di atas untuk memilih rentang. Kali ini, bagaimanapun, kita akan menggunakan tilde ( ~) sebagai ganti koma untuk memisahkan nomor.

Angka pertama menunjukkan garis mulai. Angka kedua memberi tahu sedgaris mana setelah garis awal yang ingin kita lihat. Angka 2 berarti setiap baris kedua, 3 berarti setiap baris ketiga, dan seterusnya.

Kami mengetik berikut ini:

sed -n '1 ~ 2p' coleridge.txt

Anda tidak akan selalu tahu di mana letak teks yang Anda cari di dalam file, yang berarti nomor baris tidak akan selalu membantu. Namun, Anda juga dapat menggunakan sed untuk memilih baris yang berisi pola teks yang cocok. Misalnya, mari ekstrak semua baris yang dimulai dengan "Dan".

Tanda sisipan ( ^) mewakili awal baris. Kami akan menyertakan istilah penelusuran kami dalam garis miring ( /). Kami juga menyertakan spasi setelah "Dan" sehingga kata-kata seperti "Android" tidak akan disertakan dalam hasil.

Membaca sedskrip bisa jadi agak sulit pada awalnya. The /p berarti “cetak,” sama seperti yang dilakukannya dalam perintah kita gunakan di atas. Namun, dalam perintah berikut, garis miring di depannya:

sed -n '/ ^ Dan / p' coleridge.txt

Tiga baris yang dimulai dengan "And" diekstrak dari file dan ditampilkan untuk kita.

Membuat Substitusi

Dalam contoh pertama kami, kami menunjukkan kepada Anda format dasar berikut untuk sedsubstitusi:

echo howtogonk | sed 's / gonk / geek /'

Yang smengatakan sed ini adalah substitusi. String pertama adalah pola pencarian, dan yang kedua adalah teks yang ingin kita ganti teks yang cocok tersebut. Tentu saja, seperti semua hal tentang Linux, masalahnya ada pada detailnya.

Kami mengetik berikut ini untuk mengubah semua kemunculan "hari" menjadi "minggu", dan memberikan lebih banyak waktu bagi pelaut dan elang laut untuk terikat:

sed -n 's / day / week / p' coleridge.txt

Pada baris pertama, hanya kemunculan kedua dari "hari" yang diubah. Ini karena sedberhenti setelah pertandingan pertama per baris. Kita harus menambahkan "g" di akhir ekspresi, seperti yang ditunjukkan di bawah ini, untuk melakukan pencarian global sehingga semua kecocokan di setiap baris diproses:

sed -n 's / day / week / gp' coleridge.txt

Ini cocok dengan tiga dari empat di baris pertama. Karena kata pertama adalah "Hari", dan sedpeka huruf besar / kecil, kata tersebut tidak menganggap contoh tersebut sama dengan "hari".

Kami mengetik berikut ini, menambahkan sebuah i ke perintah di akhir ekspresi untuk menunjukkan case-insensitivity:

sed -n 's / day / week / gip' coleridge.txt

Ini berfungsi, tetapi Anda mungkin tidak selalu ingin mengaktifkan case-insensitivity untuk semuanya. Dalam contoh tersebut, Anda dapat menggunakan grup regex untuk menambahkan ketidaksensitifan huruf khusus pola.

Misalnya, jika kita mengapit karakter dalam tanda kurung siku ( []), mereka ditafsirkan sebagai "karakter apa pun dari daftar karakter ini".

Kami mengetik yang berikut, dan menyertakan "D" dan "d" di grup, untuk memastikannya cocok dengan "Hari" dan "hari":

sed -n 's / [Hh] ay / minggu / gp' coleridge.txt

Kami juga dapat membatasi substitusi ke beberapa bagian file. Katakanlah file kita berisi spasi yang aneh di ayat pertama. Kita dapat menggunakan perintah familiar berikut untuk melihat ayat pertama:

sed -n '1,4p' coleridge.txt

Kami akan mencari dua spasi dan menggantinya dengan satu. Kami akan melakukan ini secara global sehingga tindakan diulangi di seluruh baris. Agar jelas, pola pencariannya adalah spasi, spasi tanda bintang ( *), dan string substitusi adalah spasi tunggal. The 1,4membatasi substitusi kepada empat baris pertama dari file.

Kami menggabungkan semua itu dalam perintah berikut:

sed -n '1,4 s / * / / gp' coleridge.txt

Ini bekerja dengan baik! Pola pencarian adalah yang penting di sini. Tanda bintang ( *) mewakili nol atau lebih dari karakter sebelumnya, yang merupakan spasi. Jadi, pola pencarian mencari string dari satu spasi atau lebih.

Jika kita mengganti satu spasi untuk setiap urutan dari beberapa spasi, kita akan mengembalikan file ke spasi reguler, dengan satu spasi di antara setiap kata. Ini juga akan menggantikan satu spasi untuk satu spasi dalam beberapa kasus, tetapi ini tidak akan memengaruhi apa pun secara negatif — kami masih akan mendapatkan hasil yang diinginkan.

Jika kita mengetik yang berikut ini dan mengurangi pola pencarian menjadi satu spasi, Anda akan segera melihat mengapa kita harus menyertakan dua spasi:

sed -n '1,4 s / * / / gp' coleridge.txt

Karena tanda bintang cocok dengan nol atau lebih dari karakter sebelumnya, ia melihat setiap karakter yang bukan spasi sebagai "spasi nol" dan menerapkan substitusinya.

Namun, jika kita memasukkan dua spasi dalam pola pencarian,  sedharus menemukan setidaknya satu karakter spasi sebelum menerapkan substitusi. Ini memastikan karakter nonspace tetap tidak tersentuh.

Kami mengetik yang berikut, menggunakan -e(ekspresi) yang kami gunakan sebelumnya, yang memungkinkan kami membuat dua atau lebih substitusi secara bersamaan:

sed -n -e 's / motion / flutter / gip' -e 's / ocean / gutter / gip' coleridge.txt

Kita bisa mendapatkan hasil yang sama jika kita menggunakan titik koma ( ;) untuk memisahkan dua ekspresi, seperti:

sed -n 's / motion / flutter / gip; s / ocean / gutter / gip' coleridge.txt

Saat kami menukar "hari" dengan "minggu" di perintah berikut, contoh "hari" dalam ekspresi "baik-baik saja" juga ditukar:

sed -n 's / [Hh] ay / minggu / gp' coleridge.txt

Untuk mencegah hal ini, kita hanya dapat mencoba mengganti garis yang cocok dengan pola lain. Jika kita memodifikasi perintah agar memiliki pola pencarian di awal, kita hanya akan mempertimbangkan untuk beroperasi pada baris yang cocok dengan pola itu.

Kami mengetik berikut ini untuk membuat pola pencocokan kami menjadi kata "setelah":

sed -n '/ setelah / s / [Hh] ay / minggu / gp' coleridge.txt

Itu memberi kita tanggapan yang kita inginkan.

Substitusi yang Lebih Kompleks

Mari beri Coleridge istirahat dan gunakan seduntuk mengekstrak nama dari etc/passwdfile.

Ada cara yang lebih singkat untuk melakukan ini (lebih lanjut tentang itu nanti), tapi kita akan menggunakan cara yang lebih panjang di sini untuk mendemonstrasikan konsep lain. Setiap item yang cocok dalam pola pencarian (disebut subekspresi) dapat diberi nomor (hingga maksimum sembilan item). Anda kemudian dapat menggunakan angka-angka ini dalam sedperintah Anda  untuk mereferensikan subekspresi tertentu.

Anda harus menyertakan subekspresi dalam tanda kurung [ ()] agar ini berfungsi. Tanda kurung juga harus diawali dengan garis miring ke belakang ( \) untuk mencegahnya diperlakukan sebagai karakter normal.

Untuk melakukan ini, Anda harus mengetik berikut ini:

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

Mari kita uraikan ini:

  • sed 's/: The sedkomando dan awal ekspresi substitusi.
  • \(: Tanda kurung pembuka [ (] yang menyertakan subekspresi, diawali dengan garis miring terbalik ( \).
  • [^:]*: Subekspresi pertama dari istilah penelusuran berisi grup dalam tanda kurung siku. Tanda sisipan ( ^) berarti "tidak" saat digunakan dalam grup. Grup berarti setiap karakter yang bukan titik dua ( :) akan diterima sebagai kecocokan.
  • \): Tanda kurung penutup [ )] dengan garis miring terbalik ( \) sebelumnya .
  • .*: Subekspresi penelusuran kedua ini berarti "karakter apa pun dan berapa pun jumlahnya".
  • /\1: Bagian substitusi dari ekspresi berisi 1diawali dengan garis miring terbalik ( \). Ini mewakili teks yang cocok dengan subekspresi pertama.
  • /': Penutupan garis miring ( /) dan tanda kutip tunggal ( ') menghentikan sedperintah.

Artinya semua ini adalah kita akan mencari string karakter apa pun yang tidak mengandung titik dua ( :), yang akan menjadi contoh pertama dari teks yang cocok. Kemudian, kami mencari hal lain di baris itu, yang akan menjadi contoh kedua dari teks yang cocok. Kami akan mengganti seluruh baris dengan teks yang cocok dengan subekspresi pertama.

Setiap baris dalam /etc/passwdfile dimulai dengan nama pengguna yang diakhiri titik dua. Kami mencocokkan semuanya dengan titik dua pertama, dan kemudian mengganti nilai itu untuk seluruh baris. Jadi, kami telah mengisolasi nama pengguna.

Selanjutnya, kita akan mengapit subekspresi kedua dalam tanda kurung [ ()] sehingga kita dapat mereferensikannya dengan angka, juga. Kami juga akan mengganti \1 dengan \2. Perintah kami sekarang akan mengganti seluruh baris dengan segala sesuatu mulai dari titik dua pertama ( :) hingga akhir baris.

Kami mengetik berikut ini:

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

Perubahan kecil itu membalikkan arti dari perintah tersebut, dan kami mendapatkan semuanya kecuali nama pengguna.

Sekarang, mari kita lihat cara cepat dan mudah untuk melakukan ini.

Istilah penelusuran kami berasal dari titik dua pertama ( :) hingga akhir baris. Karena ekspresi substitusi kita kosong ( //), kita tidak akan mengganti teks yang cocok dengan apapun.

Jadi, kami mengetik yang berikut ini, memotong semuanya dari titik dua pertama ( :) hingga akhir baris, hanya menyisakan nama pengguna:

sed 's /:.*// "/ etc / passwd

Mari kita lihat contoh di mana kami mereferensikan pertandingan pertama dan kedua dalam perintah yang sama.

Kami punya file koma ( ,) yang memisahkan nama depan dan belakang. Kami ingin mencantumkannya sebagai "nama belakang, nama depan". Kita bisa menggunakan  cat, seperti yang ditunjukkan di bawah ini, untuk melihat apa yang ada di file:

kucing geeks.txt

Seperti banyak sedperintah lainnya, perintah berikut ini pada awalnya mungkin terlihat tidak dapat ditembus:

sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt

Ini adalah perintah substitusi seperti yang telah kita gunakan, dan pola pencariannya cukup mudah. Kami akan memecahnya di bawah ini:

  • sed 's/: Perintah substitusi normal.
  • ^: Karena tanda sisipan tidak berada dalam grup ( []), artinya "Awal baris".
  • \(.*\),: Subekspresi pertama adalah sejumlah dari karakter apa pun. Itu diapit dalam tanda kurung [ ()], yang masing-masing diawali dengan garis miring terbalik ( \) sehingga kita bisa mereferensikannya dengan nomor. Seluruh pola pencarian kita sejauh ini diterjemahkan sebagai pencarian dari awal baris hingga koma pertama ( ,) untuk sejumlah karakter apapun.
  • \(.*\):  Subekspresi berikutnya adalah (lagi) sejumlah karakter apa pun. Itu juga diapit oleh tanda kurung [ ()], keduanya diawali dengan garis miring terbalik ( \) sehingga kita bisa mereferensikan teks yang cocok dengan angka.
  • $/: Tanda dolar ( $) mewakili akhir baris dan akan memungkinkan pencarian kita berlanjut hingga akhir baris. Kami telah menggunakan ini hanya untuk memperkenalkan tanda dolar. Kami tidak terlalu membutuhkannya di sini, karena asterisk ( *) akan berada di akhir baris dalam skenario ini. Garis miring ( /) melengkapi bagian pola pencarian.
  • \2,\1 /g': Karena kami menyertakan dua subekspresi kami dalam tanda kurung, kami dapat merujuk keduanya dengan nomornya. Karena kami ingin membalik urutan, kami mengetiknya sebagai second-match,first-match. Angka harus diawali dengan garis miring terbalik ( \).
  • /g: Ini memungkinkan perintah kami untuk bekerja secara global di setiap baris.
  • geeks.txt: File yang sedang kami kerjakan.

Anda juga dapat menggunakan perintah Potong ( c) untuk mengganti seluruh baris yang cocok dengan pola pencarian Anda. Kami mengetik berikut ini untuk mencari baris dengan kata "neck" di dalamnya, dan menggantinya dengan string teks baru:

sed '/ neck / c Di sekitar pergelangan tangan saya digantung' coleridge.txt

Baris baru kami sekarang muncul di bagian bawah ekstrak kami.

Memasukkan Garis dan Teks

Kami juga dapat memasukkan baris dan teks baru ke dalam file kami. Untuk menyisipkan baris baru setelah yang cocok, kita akan menggunakan perintah Append ( a).

Inilah file yang akan kami kerjakan:

kucing geeks.txt

Kami telah memberi nomor pada barisnya agar ini sedikit lebih mudah diikuti.

Kami mengetik berikut ini untuk mencari baris yang berisi kata "He," dan menyisipkan baris baru di bawahnya:

sed '/ He / a -> Dimasukkan!' geeks.txt

Kami mengetik berikut ini dan menyertakan Insert Command ( i) untuk menyisipkan baris baru di atas yang berisi teks yang cocok:

sed '/ He / i -> Dimasukkan!' geeks.txt

Kita bisa menggunakan ampersand ( &), yang mewakili teks asli yang cocok, untuk menambahkan teks baru ke baris yang cocok. \1 ,  \2, Dan sebagainya, mewakili subexpressions pencocokan.

Untuk menambahkan teks ke awal baris, kita akan menggunakan perintah substitusi yang cocok dengan semua yang ada di baris, dikombinasikan dengan klausa pengganti yang menggabungkan teks baru kita dengan baris asli.

Untuk melakukan semua ini, kami mengetik yang berikut:

sed 's /.*/--> Disisipkan & /' geeks.txt

Kami mengetik berikut ini, termasuk Gperintah, yang akan menambahkan baris kosong di antara setiap baris:

sed 'G' geeks.txt

Jika Anda ingin menambahkan dua atau lebih baris kosong, Anda dapat menggunakan G;GG;G;Gdan sebagainya.

Menghapus Garis

Perintah Hapus ( d) menghapus baris yang cocok dengan pola pencarian, atau yang ditentukan dengan nomor baris atau rentang.

Misalnya, untuk menghapus baris ketiga, kita akan mengetik berikut ini:

sed '3d' geeks.txt

Untuk menghapus rentang baris empat hingga lima, kami akan mengetik berikut ini:

sed '4,5d' geeks.txt

Untuk menghapus garis di luar rentang, kami menggunakan tanda seru ( !), seperti yang ditunjukkan di bawah ini:

sed '6,7! d' geeks.txt

Menyimpan Perubahan Anda

Sejauh ini, semua hasil kami telah dicetak ke jendela terminal, tetapi kami belum menyimpannya di mana pun. Untuk membuat ini permanen, Anda dapat menulis perubahan Anda ke file asli atau mengalihkannya ke yang baru.

Menimpa file asli Anda membutuhkan kehati-hatian. Jika sedperintah Anda salah, Anda mungkin membuat beberapa perubahan pada file asli yang sulit dibatalkan.

Untuk ketenangan pikiran, sed dapat membuat cadangan file asli sebelum menjalankan perintahnya.

Anda dapat menggunakan opsi Di tempat ( -i) untuk memberi tahu  seduntuk menulis perubahan ke file asli, tetapi jika Anda menambahkan ekstensi file ke dalamnya, sed akan mencadangkan file asli ke yang baru. Ini akan memiliki nama yang sama dengan file aslinya, tetapi dengan ekstensi file baru.

Untuk mendemonstrasikan, kami akan mencari baris yang berisi kata "He" dan menghapusnya. Kami juga akan mencadangkan file asli kami ke yang baru menggunakan ekstensi BAK.

Untuk melakukan semua ini, kami mengetik yang berikut:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt

Kami mengetik berikut ini untuk memastikan file cadangan kami tidak berubah:

kucing geeks.txt.bak

Kami juga dapat mengetik berikut ini untuk mengarahkan output ke file baru dan mencapai hasil yang serupa:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt> new_geeks.txt

Kami menggunakan catuntuk mengonfirmasi perubahan ditulis ke file baru, seperti yang ditunjukkan di bawah ini:

kucing new_geeks.txt

Memiliki semua itu

Seperti yang mungkin Anda perhatikan, primer cepat sedini pun cukup panjang. Ada banyak perintah ini, dan masih ada lagi yang dapat Anda lakukan dengannya.

Namun, semoga konsep dasar ini memberikan landasan yang kokoh yang dapat Anda bangun saat Anda terus belajar lebih banyak.