Cukup sering ketika bekerja dengan file teks Anda harus menemukan dan mengganti string teks dalam satu file atau lebih.
sed
adalah singkatan dari stream editor. Perintah sed dapat melakukan manipulasi teks dasar pada file dan input stream seperti pipe. Dengan sed, Anda dapat mencari, menemukan dan mengganti, menyisipkan, dan menghapus per kata maupun per baris. Ini mendukung regular expressions dasar maupun lanjutan yang memungkinkan Anda untuk mencocokkan pola yang kompleks.
Di artikel ini, kita akan berbicara tentang bagaimana menemukan dan mengganti string dengan sed
. Kami juga akan menunjukkan kepada Anda bagaimana melakukan pencarian dan penggantian secara rekursif.
Cara Mencari dan Mengganti String dengan sed
Ada beberapa versi sed, dengan beberapa perbedaan fungsional di antara mereka. macOS menggunakan versi BSD dan sebagian besar distribusi Linux datang dengan GNU dan telah di instal secara default. Untuk contoh kasus dalam artikel ini, Kami akan menggunakan versi GNU.
Bentuk umum search and replace teks menggunakan sed
mengambil bentuk berikut:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i
– Secara default sed menulis outputnya ke output standar. Opsi ini memberitahu Anda untuk mengedit file di tempat. Jika ekstensi diberikan (contohnya-i.bak
) backup dari file asli akan dibuat.s
– Perintah subtitusi, mungkin perintah yang paling banyak digunakan di sed./ / /
– Karakter pembatas. Bisa berupa karakter apa saja tetapi biasanya karakter garis miring (/
) digunakan.SEARCH_REGEX
– String normal atau regular expression untuk pencarian.REPLACEMENT
– String pengganti .g
– Flag pengganti global. Secara default, sed membaca file baris demi baris dan hanya mengubah kemunculan pertama padaSEARCH_REGEX
di satu baris. Ketika flag pengganti disediakan, semua kemunculan akan diganti.INPUTFILE
– Nama file tempat Anda ingin menjalankan perintah.
Merupakan praktik yang baik untuk memberikan tanda kutip di argumen agar meta-karakter shell tidak akan berkembang.
Mari kita lihat contoh cara menggunakan perintah sed
untuk search and replace teks dalam file dengan beberapa opsi dan flag yang paling umum digunakan.
Untuk tujuan demonstrasi, kita akan menggunakan file berikut:
nano file.txt
123 Foo foo foo foo /bin/bash Ubuntu foobar 456
Jika Anda menghilangkan flag g
, hanya instance pertama dari string pencarian di setiap baris yang akan diganti:
sed -i 's/foo/linux/' file.txt
123 Foo linux foo linux /bin/bash Ubuntu foobar 456
Dengan flag pengganti global sed
menggantikan semua kemunculan pola pencarian:
sed -i 's/foo/linux/g' file.txt
123 Foo linux linux linux /bin/bash Ubuntu linuxbar 456
Seperti yang mungkin Anda perhatikan, pada contoh sebelumnya substring foo
di dalam string foobar
juga diganti. Jika ini bukan perilaku yang diinginkan, gunakan ekspresi batas kata (\b
) di kedua ujung string pencarian. Ini memastikan sebagian kata tidak cocok.
sed -i 's/\bfoo\b/linux/g' file.txt
123 Foo linux linux linux /bin/bash Ubuntu foobar 456
Untuk membuat match case pola insensitive, gunakan flag I
. Pada contoh di bawah ini kita menggunakan flag g
dan I
:
sed -i 's/foo/linux/gI' file.txt
123 linux linux linux linux /bin/bash Ubuntu linuxbar 456
Jika Anda ingin menemukan dan mengganti string yang berisi karakter pembatas (/
), Anda harus menggunakan garis miring terbalik (\
) untuk escape dari garis miring. Misalnya untuk mengganti /bin/bash
dengan /usr/bin/zsh
, berikut yang akan Anda gunakan
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
Opsi yang lebih mudah dan lebih mudah dibaca adalah menggunakan karakter pembatas lainnya. Kebanyakan orang menggunakan bilah vertikal (|
) atau titik dua (:
) . Anda juga dapat menggunakan karakter lain:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo foo /usr/bin/zsh Ubuntu foobar 456
Anda juga dapat menggunakan regular expressions. Misalnya untuk mencari semua angka dengan 3 digit dan menggantinya dengan string number
, maka perintah yang akan Anda gunakan:
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo foo /bin/bash demo foobar number
Fitur lain yang berguna dari sed adalah Anda dapat menggunakan karakter ampersand &
yang sesuai dengan pola yang cocok. Karakter dapat digunakan beberapa kali.
Misalnya, jika Anda ingin menambahkan kurung kurawal {} di sekitar setiap 3 digit angka, ketik:
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo foo /bin/bash demo foobar {456}
Terakhir namun tidak kalah pentingnya, selalu merupakan ide bagus untuk membuat cadangan saat mengedit file dengan sed. Untuk melakukan itu cukup berikan ekstensi ke opsi -i. Misalnya, untuk mengedit file.txt dan menyimpan file asli sebagai file.txt.bak
yang akan Anda gunakan:
sed -i.bak 's/foo/linux/g' file.txt
Jika Anda ingin memastikan bahwa backup dibuat daftar file dengan perintah ls
:
ls
file.txt file.txt.bak
Find and Replace Secara Recursive
Kadang-kadang Anda ingin mencari direktori secara rekursif untuk file yang berisi string dan mengganti string di semua file. Ini dapat dilakukan dengan menggunakan perintah seperti find
atau grep
untuk secara rekursif menemukan file dalam direktori dan mem-piping nama file ke sed
.
Perintah berikut ini akan secara rekursif mencari file di direktori kerja saat ini dan meneruskan nama file ke sed
.
find . -type f -exec sed -i 's/foo/bar/g' {} +
Untuk menghindari masalah dengan file yang mengandung spasi dalam nama mereka gunakan opsi -print0
yang memberitahu find
untuk mencetak nama file, diikuti oleh karakter null dan pipe output ke sed menggunakan xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Untuk mengecualikan direktori, gunakan opsi -not -path
. Misalnya, jika Anda mengganti sebuah string di repo git lokal Anda untuk mengecualikan semua file yang dimulai dengan dot (.
), Gunakan:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Jika Anda ingin mencari dan mengganti teks hanya pada file dengan ekstensi yang spesifik, maka perintah yang akan Anda gunakan:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Pilihan lain adalah dengan menggunakan perintah grep
untuk secara rekursif menemukan semua file yang mengandung pola pencarian dan kemudian menyalurkan nama file ke sed
:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
Kesimpulan
Meskipun terlihat rumit dan kompleks pada awalnya, mencari dan mengganti teks dalam file dengan sed
sangat sederhana.
Untuk mempelajari lebih lanjut tentang perintah, opsi, dan bendera, kunjungi manual GNU sed dan tutorial Grymoire.