Cara Menggunakan Perintah sed di Linux
Mungkin terdengar gila, tetapi sed
perintah Linux adalah penyunting teks tanpa antara muka. Anda boleh menggunakannya dari baris perintah untuk memanipulasi teks dalam fail dan aliran. Kami akan menunjukkan kepada anda bagaimana memanfaatkan kekuatannya.
Kekuatan sed
The sed
arahan adalah sedikit seperti catur: ia mengambil masa satu jam untuk belajar asas-asas dan seumur hidup untuk menguasai mereka (atau, sekurang-kurangnya banyak amalan). Kami akan menunjukkan pilihan pertunjukan pembukaan di setiap kategori sed
fungsi utama.
sed
adalah penyunting aliran yang berfungsi pada input paip atau fail teks. Namun, ia tidak mempunyai antara muka penyunting teks interaktif. Sebaliknya, anda memberikan arahan untuk mengikutinya kerana ia berfungsi melalui teks. Ini semua berfungsi di Bash dan shell baris perintah yang lain.
Dengan sed
anda boleh melakukan semua perkara berikut:
- Pilih teks
- Teks pengganti
- Tambahkan baris ke teks
- Padamkan baris dari teks
- Ubah (atau simpan) fail asal
Kami telah menyusun contoh-contoh kami untuk memperkenalkan dan menunjukkan konsep, bukan untuk menghasilkan perintah yang paling pendek (dan paling tidak dapat didekati) sed
. Walau bagaimanapun, fungsi pemadanan corak dan pemilihan teks sed
sangat bergantung pada ungkapan biasa (regex). Anda akan memerlukan beberapa keakraban dengan ini untuk mendapatkan yang terbaik sed
.
BERKAITAN: Cara Menggunakan Ekspresi Biasa (regex) di Linux
Contoh Mudah
Pertama, kita akan gunakan echo
untuk menghantar beberapa teks sed
melalui paip, dan sed
mengganti sebahagian teks. Untuk melakukannya, kami taipkan perkara berikut:
echo howtogonk | sed 's / gonk / geek /'
The echo
arahan menghantar "howtogonk" ke dalam sed
, dan peraturan penggantian mudah kami ( "s" bermaksud penggantian) digunakan. sed
mencari teks input untuk terjadinya rentetan pertama, dan akan menggantikan sebarang padanan dengan yang kedua.
Rentetan "gonk" diganti dengan "geek", dan rentetan baru dicetak di tetingkap terminal.
Penggantian mungkin merupakan penggunaan yang paling biasa sed
. Sebelum kita dapat menyelami pengganti dengan lebih mendalam, kita perlu tahu bagaimana memilih dan memadankan teks.
Memilih Teks
Kami akan memerlukan fail teks untuk contoh kami. Kami akan menggunakan satu yang berisi pilihan ayat dari puisi epik Samuel Taylor Coleridge "The Rime of the Ancient Mariner."
Kami menaip perkara berikut untuk melihatnya dengan less
:
kurang coleridge.txt
Untuk memilih beberapa baris dari fail, kami menyediakan garis permulaan dan akhir julat yang ingin kami pilih. Nombor tunggal memilih satu baris.
Untuk mengekstrak baris satu hingga empat, kami taipkan arahan ini:
sed -n '1,4p' coleridge.txt
Perhatikan tanda koma antara 1
dan 4
. Yang p
bermaksud "mencetak garis dipadankan." Secara lalai, sed
mencetak semua baris. Kami akan melihat semua teks dalam fail dengan garis yang sesuai dicetak dua kali. Untuk mengelakkannya, kami akan menggunakan pilihan -n
(senyap) untuk menekan teks yang tidak sepadan.
Kami menukar nombor garis sehingga kami dapat memilih ayat yang berbeza, seperti yang ditunjukkan di bawah:
sed -n '6,9p' coleridge.txt
Kita boleh menggunakan pilihan -e
(ekspresi) untuk membuat beberapa pilihan. Dengan dua ungkapan, kita dapat memilih dua ayat, seperti:
sed -n -e '1,4p' -e '31, 34p 'coleridge.txt
Sekiranya kita mengurangkan nombor pertama dalam ungkapan kedua, kita dapat memasukkan kosong di antara dua ayat tersebut. Kami menaip perkara berikut:
sed -n -e '1,4p' -e '30, 34p 'coleridge.txt
Kami juga dapat memilih baris permulaan dan memberitahu sed
untuk melangkah ke fail dan mencetak baris gantian, setiap baris kelima, atau melangkau sebilangan baris. Perintahnya serupa dengan yang kami gunakan di atas untuk memilih julat. Akan tetapi, kali ini kita akan menggunakan tilde ( ~
) dan bukan koma untuk memisahkan angka.
Nombor pertama menunjukkan garis permulaan. Nombor kedua memberitahu sed
baris mana selepas garis permulaan yang ingin kita lihat. Nombor 2 bermaksud setiap baris kedua, 3 bermaksud setiap baris ketiga, dan seterusnya.
Kami menaip perkara berikut:
sed -n '1 ~ 2p' coleridge.txt
Anda tidak akan selalu mengetahui di mana teks yang anda cari berada di dalam fail, yang bermaksud nombor baris tidak akan banyak membantu. Namun, anda juga dapat menggunakan sed
untuk memilih baris yang berisi pola teks yang sepadan. Sebagai contoh, mari kita ekstrak semua baris yang bermula dengan "Dan".
Caret ( ^
) mewakili permulaan garis. Kami akan memasukkan istilah carian kami dalam garis miring ke depan ( /
). Kami juga menyertakan spasi setelah "Dan" sehingga kata-kata seperti "Android" tidak akan disertakan dalam hasilnya.
Membaca sed
skrip pada awalnya agak sukar. Yang /p
bermaksud "cetak," hanya seperti yang berlaku dalam perintah-perintah kami yang digunakan di atas. Namun, dalam perintah berikut, garis miring ke depan mendahului:
sed -n '/ ^ Dan / p' coleridge.txt
Tiga baris yang dimulakan dengan "Dan" diekstrak dari fail dan dipaparkan untuk kita.
Membuat Penggantian
Dalam contoh pertama kami, kami menunjukkan format asas sed
pengganti berikut:
echo howtogonk | sed 's / gonk / geek /'
Yang s
memberitahu sed
ini adalah penggantian. Rentetan pertama adalah corak carian, dan yang kedua adalah teks yang dengannya kami mahu mengganti teks yang sesuai. Sudah tentu, seperti semua perkara Linux, syaitan ada dalam perinciannya.
Kami menaip yang berikut untuk mengubah semua kejadian "hari" menjadi "minggu", dan memberi lebih banyak masa kepada pelaut dan albatros untuk mengikat:
sed -n / s / hari / minggu / p 'coleridge.txt
Pada baris pertama, hanya kejadian kedua "hari" yang diubah. Ini kerana sed
berhenti selepas perlawanan pertama setiap baris. Kita harus menambahkan "g" di akhir ungkapan, seperti yang ditunjukkan di bawah, untuk melakukan carian global sehingga semua pertandingan di setiap baris diproses:
sed -n / s / hari / minggu / gp 'coleridge.txt
Ini sesuai dengan tiga daripada empat di barisan pertama. Kerana kata pertama adalah "Hari", dan sed
peka huruf besar kecil, kata ini tidak menganggap kejadian itu sama dengan "hari".
Kami menaip yang berikut, menambahkan i
perintah pada akhir ungkapan untuk menunjukkan ketidakpekaan huruf besar-kecil:
sed -n 's / hari / minggu / gip' coleridge.txt
Ini berfungsi, tetapi anda mungkin tidak selalu mahu menghidupkan kepekaan huruf besar-besaran untuk semuanya. Dalam keadaan seperti itu, anda boleh menggunakan kumpulan regex untuk menambahkan ketidakpekaan kes khusus corak.
Sebagai contoh, jika kita memasukkan watak dalam tanda kurung persegi ( []
), mereka ditafsirkan sebagai "watak apa pun dari senarai watak ini."
Kami menaip yang berikut, dan memasukkan "D" dan "d" dalam kumpulan, untuk memastikannya sesuai dengan "Hari" dan "hari":
sed -n / s / [dd] ay / minggu / gp 'coleridge.txt
Kami juga boleh menyekat penggantian pada bahagian fail. Katakan fail kami mengandungi jarak yang pelik pada ayat pertama. Kita boleh menggunakan perintah biasa berikut untuk melihat ayat pertama:
sed -n '1,4p' coleridge.txt
Kami akan mencari dua ruang dan menggantinya dengan satu. Kami akan melakukan ini secara global sehingga tindakan diulang secara keseluruhan. Untuk jelas, corak carian adalah ruang, asterisk ruang ( *
), dan rentetan penggantian adalah ruang tunggal. Yang 1,4
menyekat penggantian kepada empat baris pertama fail.
Kami mengumpulkan semua itu dalam arahan berikut:
sed -n '1,4 s / * / / gp' coleridge.txt
Ini berfungsi dengan baik! Corak carian adalah yang penting di sini. Tanda bintang ( *
) mewakili sifar atau lebih daripada watak sebelumnya, yang merupakan spasi. Oleh itu, corak carian mencari rentetan satu ruang atau lebih.
Sekiranya kita menggantikan satu ruang untuk urutan pelbagai ruang, kita akan mengembalikan fail ke jarak biasa, dengan satu ruang di antara setiap perkataan. Ini juga akan menggantikan satu ruang untuk satu ruang dalam beberapa kes, tetapi ini tidak akan mempengaruhi apa-apa yang buruk - kita masih akan mendapat hasil yang diinginkan.
Sekiranya kita memasukkan perkara berikut dan mengurangkan corak carian menjadi satu ruang, anda akan melihat dengan segera mengapa kita mesti memasukkan dua ruang:
sed -n '1,4 s / * / / gp' coleridge.txt
Kerana tanda bintang sepadan dengan sifar atau lebih daripada watak sebelumnya, ia melihat setiap watak yang bukan ruang sebagai "ruang sifar" dan menerapkan penggantian untuknya.
Walau bagaimanapun, jika kita memasukkan dua ruang dalam corak carian, sed
mesti mencari sekurang-kurangnya satu watak ruang sebelum menerapkan penggantian. Ini memastikan watak-watak nonspace tidak akan tersentuh
Kami menaip yang berikut, menggunakan -e
(ungkapan) yang kami gunakan sebelumnya, yang membolehkan kami membuat dua atau lebih penggantian secara serentak:
sed -n -e / s / motion / flutter / gip '-e' s / ocean / gutter / gip 'coleridge.txt
Kita boleh mencapai hasil yang sama jika kita menggunakan titik koma ( ;
) untuk memisahkan dua ungkapan, seperti:
sed -n 's / motion / flutter / gip; s / ocean / gutter / gip' coleridge.txt
Ketika kami menukar "hari" untuk "minggu" dalam perintah berikut, contoh "hari" dalam ungkapan "baik sehari" juga ditukar:
sed -n / s / [dd] ay / minggu / gp 'coleridge.txt
Untuk mengelakkan ini, kita hanya boleh mencuba penggantian pada garis yang sesuai dengan corak lain. Sekiranya kita mengubah perintah untuk mempunyai corak carian pada permulaannya, kita hanya akan mempertimbangkan untuk beroperasi pada garis yang sesuai dengan corak itu.
Kami menaip yang berikut untuk menjadikan corak pencocokan kami dengan kata "setelah":
sed -n '/ after / s / [Dd] ay / week / gp' coleridge.txt
Itu memberi kita respons yang kita mahukan.
Penggantian Lebih Kompleks
Mari beri rehat dan gunakan Coleridge sed
untuk mengekstrak nama dari etc/passwd
fail.
Terdapat cara yang lebih pendek untuk melakukan ini (lebih lanjut kemudian), tetapi kita akan menggunakan cara yang lebih panjang di sini untuk menunjukkan konsep lain. Setiap item yang sesuai dalam corak pencarian (disebut subekspresi) dapat bernomor (hingga maksimum sembilan item). Anda kemudian boleh menggunakan nombor ini dalam sed
perintah anda untuk merujuk subekspresi tertentu.
Anda mesti memasukkan subekspresi dalam kurungan [ ()
] agar ini berfungsi. Tanda kurung juga mesti didahului dengan garis miring ke belakang ( \
) untuk mengelakkannya diperlakukan sebagai watak normal.
Untuk melakukan ini, anda akan menaip perkara berikut:
sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd
Mari pecahkan ini:
sed 's/
: Thesed
arahan dan permulaan ungkapan penggantian.\(
: Tanda kurung pembuka [(
] merangkumi subekspresi, didahului dengan garis miring terbalik (\
).[^:]*
: Subekspresi pertama istilah carian mengandungi kumpulan dalam tanda kurung persegi. Caret (^
) bermaksud "tidak" apabila digunakan dalam kumpulan. Kumpulan bermaksud setiap watak yang bukan titik dua (:
) akan diterima sebagai padanan.\)
: Tanda kurung penutup [)
] dengan garis miring terbalik (\
)..*
: Subekspresi carian kedua ini bermaksud "watak apa pun dan sebilangannya."/\1
: Bahagian penggantian ungkapan mengandungi1
didahului dengan garis miring terbalik (\
). Ini mewakili teks yang sepadan dengan subekspresi pertama./'
: Slash ke depan penutup (/
) dan petikan tunggal ('
) menamatkansed
perintah.
Apa maksudnya ini adalah kita akan mencari rentetan watak yang tidak mengandungi titik dua ( :
), yang akan menjadi contoh pertama teks yang sepadan. Kemudian, kami mencari perkara lain di baris itu, yang akan menjadi contoh kedua teks yang sepadan. Kami akan mengganti keseluruhan baris dengan teks yang sepadan dengan subekspresi pertama.
Setiap baris dalam /etc/passwd
fail bermula dengan nama pengguna yang diakhiri dengan titik dua. Kami memadankan semuanya hingga titik dua pertama, dan kemudian menggantikan nilai itu dengan keseluruhan garis. Oleh itu, kami telah mengasingkan nama pengguna.
Seterusnya, kami akan memasukkan subekspresi kedua dalam tanda kurung [ ()
] sehingga kami juga dapat merujuknya dengan nombor. Kami juga akan menggantikan \1
dengan \2
. Perintah kami sekarang akan mengganti keseluruhan baris dengan segala-galanya dari titik dua ( :
) hingga akhir baris.
Kami menaip perkara berikut:
sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd
Perubahan kecil itu membalikkan makna perintah, dan kami mendapat segalanya kecuali nama pengguna.
Sekarang, mari kita lihat cara cepat dan mudah untuk melakukan ini.
Istilah carian kami adalah dari titik dua pertama ( :
) hingga akhir baris. Kerana ungkapan penggantian kami kosong ( //
), kami tidak akan mengganti teks yang dipadankan dengan apa-apa.
Oleh itu, kami taipkan perkara berikut, memotong segala-galanya dari titik dua pertama ( :
) hingga akhir baris, hanya tinggal nama pengguna:
sed 's /:.*// "/ etc / passwd
Mari kita lihat contoh di mana kita merujuk perlawanan pertama dan kedua dalam arahan yang sama.
Kami mempunyai fail koma ( ,
) yang memisahkan nama depan dan belakang. Kami ingin menyenaraikannya sebagai "nama belakang, nama depan." Kita dapat menggunakan cat
, seperti gambar di bawah, untuk melihat apa yang ada di dalam file:
kucing geeks.txt
Seperti banyak sed
perintah, yang berikutnya mungkin kelihatan tidak dapat ditembus pada mulanya:
sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt
Ini adalah arahan penggantian seperti yang lain yang telah kami gunakan, dan corak cariannya agak mudah. Kami akan memecahkannya di bawah:
sed 's/
: Perintah penggantian biasa.^
: Kerana karet tidak berada dalam kumpulan ([]
), itu bermaksud "Permulaan baris."\(.*\),
: Subekspresi pertama adalah sebilangan besar aksara. Ini dibungkus dalam tanda kurung [()
], yang masing-masing didahului dengan garis miring terbalik (\
) sehingga kita dapat merujuknya dengan angka. Seluruh corak carian kami setakat ini diterjemahkan sebagai carian dari awal baris hingga koma pertama (,
) untuk sebilangan besar watak mana pun.\(.*\)
: Subekspresi seterusnya adalah (sekali lagi) sebilangan watak apa pun. Ini juga disertakan dalam tanda kurung [()
], yang keduanya didahului dengan garis miring terbalik (\
) sehingga kita dapat merujuk teks yang sesuai dengan angka.$/
: Tanda dolar ($
) mewakili akhir garis dan akan membolehkan carian kami berterusan hingga akhir baris. Kami menggunakan ini hanya untuk memperkenalkan tanda dolar. Kami tidak benar-benar memerlukannya di sini, kerana tanda bintang (*
) akan sampai ke hujung baris dalam senario ini. Garis depan (/
) melengkapkan bahagian corak carian.\2,\1 /g'
: Kerana kami memasukkan dua subekspresi kami dalam kurungan, kami dapat merujuk kedua-duanya dengan nombor mereka. Oleh kerana kami mahu membalikkan susunan, kami taipkannya sebagaisecond-match,first-match
. Nombor mesti didahului dengan garis miring terbalik (\
)./g
: Ini membolehkan perintah kita berfungsi secara global di setiap baris.geeks.txt
: Fail yang sedang kami jalankan.
Anda juga boleh menggunakan perintah Potong ( c
) untuk menggantikan keseluruhan baris yang sesuai dengan corak carian anda. Kami menaip yang berikut untuk mencari baris dengan kata "leher" di dalamnya, dan menggantinya dengan rentetan teks baru:
sed '/ leher / c Di sekitar pergelangan tangan saya digantung' coleridge.txt
Baris baru kami kini muncul di bahagian bawah ekstrak kami.
Memasukkan Garis dan Teks
Kami juga boleh memasukkan baris dan teks baru ke dalam fail kami. Untuk memasukkan baris baru setelah ada yang sesuai, kami akan menggunakan perintah Lampirkan ( a
)
Inilah fail yang akan kami bekerjasama:
kucing geeks.txt
Kami telah memberi nombor untuk menjadikannya lebih mudah diikuti.
Kami menaip yang berikut untuk mencari baris yang mengandungi perkataan "Dia", dan memasukkan baris baru di bawahnya:
sed '/ He / a -> Dimasukkan!' geeks.txt
Kami menaip yang berikut dan memasukkan Command Insert ( i
) untuk memasukkan baris baru di atas yang mengandungi teks yang sepadan:
sed '/ He / i -> Dimasukkan!' geeks.txt
Kita dapat menggunakan ampersand ( &
), yang mewakili teks asli yang sesuai, untuk menambahkan teks baru ke garis yang sesuai. \1
, \2
, Dan sebagainya, mewakili subexpressions sepadan.
Untuk menambahkan teks ke permulaan baris, kami akan menggunakan perintah penggantian yang sesuai dengan semua yang ada di baris, digabungkan dengan klausa penggantian yang menggabungkan teks baru kami dengan baris asal.
Untuk melakukan semua ini, kami taipkan perkara berikut:
sed 's /.*/--> Disisipkan & /' geeks.txt
Kami menaip yang berikut, termasuk G
perintah, yang akan menambahkan baris kosong di antara setiap baris:
sed 'G' geeks.txt
Jika anda ingin menambah dua atau lebih baris kosong, anda boleh menggunakan G;G
, G;G;G
dan sebagainya.
Memadamkan Garis
Perintah Hapus ( d
) menghapus baris yang sesuai dengan corak carian, atau yang ditentukan dengan nombor atau julat garis.
Sebagai contoh, untuk menghapus baris ketiga, kami akan menaip perkara berikut:
sed '3d' geeks.txt
Untuk menghapus julat baris empat hingga lima, kami taipkan yang berikut:
sed '4,5d' geeks.txt
Untuk menghapus garis di luar jarak, kami menggunakan tanda seru ( !
), seperti yang ditunjukkan di bawah:
sed '6,7! d' geeks.txt
Menyimpan Perubahan Anda
Sejauh ini, semua hasil kami telah dicetak ke tetingkap terminal, tetapi kami belum menyimpannya di mana sahaja. Untuk menjadikannya tetap, anda boleh menulis perubahan anda ke fail asal atau mengalihkannya ke fail baru.
Menimpa fail asal anda memerlukan berhati-hati. Sekiranya sed
arahan anda salah, anda mungkin membuat beberapa perubahan pada fail asal yang sukar dibatalkan.
Untuk ketenangan hati, sed
boleh membuat sandaran fail asal sebelum melaksanakan perintahnya.
Anda boleh menggunakan pilihan Di tempat ( -i
) untuk memberitahu sed
untuk menulis perubahan pada fail asal, tetapi jika anda menambahkan pelanjutan fail ke file tersebut, sed
akan membuat sandaran fail asal ke yang baru. Ia akan mempunyai nama yang sama dengan fail asal, tetapi dengan sambungan fail baru.
Untuk menunjukkan, kami akan mencari mana-mana baris yang mengandungi perkataan "Dia" dan menghapusnya. Kami juga akan menyandarkan fail asal kami ke fail baru menggunakan pelanjutan BAK.
Untuk melakukan semua ini, kami taipkan perkara berikut:
sed -i'.bak '' /^.*He.*$/d 'geeks.txt
Kami menaip perkara berikut untuk memastikan fail sandaran kami tidak berubah:
kucing geeks.txt.bak
Kami juga boleh mengetik berikut untuk mengalihkan output ke fail baru dan mencapai hasil yang serupa:
sed -i'.bak '' /^.*He.*$/d 'geeks.txt> new_geeks.txt
Kami gunakan cat
untuk mengesahkan perubahan ditulis ke file baru, seperti yang ditunjukkan di bawah ini:
kucing baru_geeks.txt
Mempunyai semua itu
Seperti yang anda mungkin perhatikan, walaupun buku asas cepat sed
ini cukup panjang. Terdapat banyak perintah ini, dan ada banyak lagi yang boleh anda lakukan dengannya.
Walau bagaimanapun, semoga konsep asas ini memberikan asas yang kukuh di mana anda dapat membangun semasa anda terus mempelajari lebih lanjut.