sed menyisipkan baris ke dalam file. Kami menggunakan editor teks streaming sed di Linux. Menghapus baris berdasarkan konteks

24.06.2020 drive SSD

Pengarang: Rares Aioanei
Tanggal publikasi: 19 November 2011
Terjemahan: A. Krivoshey
Tanggal transfer: Juli 2012

1. Perkenalan

Selamat datang di bagian kedua dari seri kami tentang sed, versi GNU. Ada beberapa versi sed yang tersedia di platform yang berbeda, tapi kami akan fokus pada GNU sed versi 4.x. Banyak dari Anda pernah mendengar tentang sed, atau sudah menggunakannya, kemungkinan besar sebagai alat pengganti. Tetapi ini hanya salah satu tujuan dari sed, dan kami akan mencoba menunjukkan kepada Anda semua aspek penggunaan utilitas ini. Namanya adalah singkatan dari "Stream EDitor" dan kata "stream" (aliran) dalam hal ini bisa berarti file, pipa, atau hanya stdin. Kami harap Anda sudah memiliki pengetahuan dasar tentang Linux, dan jika Anda telah bekerja dengan ekspresi reguler, atau setidaknya tahu apa itu, maka semuanya akan jauh lebih mudah bagi Anda. Volume artikel tidak memungkinkan termasuk panduan lengkap pada ekspresi reguler, sebagai gantinya kita akan membahas konsep dasar dan memberikan banyak contoh bagaimana menggunakan sed.

2. Instalasi

Tidak banyak yang bisa dikatakan di sini. Kemungkinan besar Anda sudah menginstal sed, karena digunakan oleh berbagai skrip sistem, serta pengguna Linux yang ingin meningkatkan kinerjanya. Anda dapat mengetahui versi sed mana yang telah Anda instal dengan perintah:

$ sed --versi

Di sistem saya, perintah ini menunjukkan bahwa saya telah menginstal GNU sed 4.2.1 plus tautan ke beranda program dan informasi berguna lainnya. Paket tersebut diberi nama "sed" terlepas dari distribusinya, kecuali untuk Gentoo, di mana ia hadir secara implisit.

3. Konsep

Sebelum melangkah lebih jauh, kami pikir penting untuk fokus pada apa yang "sed" lakukan, karena "stream editor" tidak banyak bicara tentang tujuannya. sed mengambil teks sebagai input, mengeksekusi operasi tertentu di atas setiap baris (kecuali ditentukan lain) dan menampilkan teks yang dimodifikasi. Operasi ini dapat menambah, menyisipkan, menghapus, atau mengganti. Ini tidak semudah kelihatannya: berhati-hatilah, ada sejumlah besar opsi dan kombinasi opsi yang dapat membuat perintah sed sangat sulit untuk dipahami. Oleh karena itu, kami menyarankan Anda mempelajari dasar-dasar ekspresi reguler untuk memahami cara kerjanya. Sebelum melanjutkan dengan panduan ini, kami ingin mengucapkan terima kasih kepada Eric Pement dan yang lainnya atas inspirasi dan apa yang telah dia lakukan untuk siapa saja yang ingin belajar dan menggunakan sed.

4. Ekspresi Reguler

Karena perintah sed (skrip) tetap menjadi misteri bagi banyak orang, kami merasa bahwa pembaca kami harus memahami konsep dasar, dan tidak menyalin dan menempelkan perintah secara membabi buta yang artinya tidak mereka pahami. Ketika seseorang ingin memahami apa itu ekspresi reguler, kata kuncinya adalah "cocok", atau lebih khusus lagi, "pola pencocokan". Misalnya, dalam laporan departemen Anda, Anda menulis nama Nick, mengacu pada arsitek jaringan. Tapi Nick pergi dan John menggantikannya, jadi sekarang Anda harus mengubah kata Nick menjadi John. Jika file laporan bernama report.txt, Anda harus menjalankan perintah berikut:

$ cat report.txt / sed "s/Nick/John/g"> report_new.txt

Secara default sed menggunakan stdout, Anda dapat menggunakan operator pengalihan output seperti yang ditunjukkan pada contoh di atas. Ini adalah contoh yang sangat sederhana, tetapi kami telah mengilustrasikan beberapa poin: kami mencari semua kecocokan dari pola "Nick" dan mengganti semuanya dengan "John". Perhatikan bahwa sed melakukan pencarian peka huruf besar-kecil, jadi berhati-hatilah dan periksa file keluaran untuk memastikan semua penggantian telah dilakukan. Contoh di atas juga dapat ditulis seperti ini:

$ sed "s/Nick/John/g" report.txt > report_new.txt

Oke, katamu, tapi di mana ekspresi reguler di sini? Ya, kami ingin menunjukkan contoh dulu, dan sekarang bagian yang paling menarik dimulai.
Jika Anda tidak yakin apakah Anda menulis "nick" atau "Nick" dan ingin menangani kedua kasus, Anda harus menggunakan perintah sed "s/Nick/nick/John/g". Bilah vertikal memiliki arti yang harus Anda ketahui jika Anda mempelajari C, artinya ekspresi Anda akan cocok dengan "nick" atau "Nick". Seperti yang akan Anda lihat di bawah, saluran dapat digunakan dengan cara lain, tetapi artinya sama. Operator lain yang biasa digunakan dalam ekspresi reguler adalah "?" yang cocok dengan nol atau satu pengulangan karakter sebelumnya (yaitu flavou?r akan cocok dengan rasa dan rasa), "*" nol kali atau lebih, "+" satu kali atau lebih. "^" cocok dengan awal baris, dan "$" sebaliknya. Jika Anda adalah pengguna vi atau vim, banyak hal akan tampak akrab bagi Anda. Bagaimanapun, utilitas ini, bersama dengan awk dan C, berakar pada hari-hari awal UNIX. Kami tidak akan membicarakan ini lagi, karena lebih mudah untuk memahami arti dari karakter ini dengan contoh, tetapi Anda harus menyadari bahwa ada berbagai implementasi ekspresi reguler: POSIX, POSIX Extended, Perl, dan berbagai implementasi ekspresi reguler fuzzy , menjamin Anda sakit kepala .

5. Contoh penggunaan sed

Sintaks perintah Keterangan
sed "s/Nick/John/g" report.txt Menggantikan setiap kemunculan Nick dengan John di report.txt
sed "s/Nick/nick/John/g" report.txt Menggantikan setiap kemunculan Nick atau nick dengan John.
sed "s/^/ /" file.txt >file_new.txt Menambahkan 8 spasi di sebelah kiri teks untuk meningkatkan kualitas cetak.
sed -n "/Tentu saja/,/perhatianmu \
bayar/p" myfile
Output satu paragraf dimulai dengan "Tentu saja" dan diakhiri dengan "perhatian yang Anda bayar"
sed -n 12.18p file.txt Hanya mengeluarkan baris 12-18 dari file.txt
sed12,18d file.txt Mencetak seluruh file file.txt kecuali baris 12 hingga 18
sed G file.txt Menggandakan spasi di file.txt
sed -f script.sed file.txt Menulis semua perintah ke script.sed dan menjalankannya.
sed "5!s/ham/cheese/" file.txt Mengganti ham dengan keju di file.txt kecuali baris ke-5
sed "$d" file.txt Menghapus baris terakhir
sed "/\(3\)/p" file.txt Hanya mencetak garis dengan tiga digit berurutan
sed "/boom/!s/aaa/bb/" file.txt Jika "boom" ditemukan, ganti aaa dengan bb
sed "17,/disk/d" file.txt Menghapus semua baris dari baris 17 hingga "disk"
echo SATU DUA / sed "s/one/unos/I" Mengganti satu dengan unos case-insensitive, jadi "unos TWO" akan dicetak
sed "G;G" file.txt Tiga spasi dalam file
sed "s/.$//" file.txt cara penggantian dos2unix :)
sed "s/^[ ^t]*//" file.txt Menghapus semua spasi sebelum setiap baris di file.txt
sed "s/[ ^t]*$//" file.txt Menghapus semua spasi di akhir setiap baris di file.txt
sed "s/^[ ^t]*//;s/[ ^]*$//" file.txt Menghapus semua spasi dari awal dan akhir setiap baris di file.txt
sed "s/foo/bar/" file.txt Mengganti foo dengan bar hanya pada kemunculan pertama dalam string.
sed "s/foo/bar/4" file.txt Menggantikan foo dengan bar hanya pada kemunculan keempat dalam string.
sed "s/foo/bar/g" file.txt Menggantikan foo dengan bar untuk semua kemunculan dalam string.
sed "/baz/s/foo/bar/g" file.txt Ganti foo dengan bar hanya jika string berisi baz.
sed "/./,/^$/!d" file.txt Hapus semua baris kosong berturut-turut kecuali EOF
sed "/^$/N;/\n$/D" file.txt Hapus semua baris kosong berturut-turut, tetapi biarkan baris kosong teratas.
sed "/./,$!d" file.txt Hapus semua baris kosong terkemuka
sed -e:a -e "/^\n*$/($d;N;);/\n$/ba" \
file.txt
Hapus semua baris kosong yang tertinggal
sed -e:a -e "/\\$/N; s/\\\n//; ta" \
file.txt
Jika file diakhiri dengan garis miring terbalik, gabungkan dengan yang berikutnya (berguna untuk skrip shell)
sed "/regex/,+5/expr/" Cocok dengan regex plus 5 baris berikut
sed "1~3d" file.txt Hapus setiap baris ketiga, dimulai dengan yang pertama.
sed -n "2~5p" file.txt Cetak setiap baris kelima, mulai dari baris kedua.
sed "s/ick/John/g" report.txt Cara lain untuk menulis beberapa contoh di atas. Bisakah Anda menyarankan milik Anda?
sed -n "/RE/(p;q;)" file.txt Hanya mencetak kecocokan pertama RE (Regular Expression)
sed "0,/RE/(//d;)" file.txt Menghapus hanya pertandingan pertama
sed "0,/RE/s//to_that/" file.txt Hanya mengubah pertandingan pertama
sed "s/^[^,]*,/9999,/" file.csv Mengubah bidang pertama menjadi 9999 dalam file CSV
s/^ *\(.*[^ ]\) *$//\1//; s/"*, */"//g; : loop s// *\([^",/][^,/]*\) *, *//\1//g; s// *, *//\1//g; t loop s / *////g;s// *///g;s/^/\(.*\)/$/\1/; Skrip sed untuk mengonversi file CSV ke file dengan bilah vertikal sebagai pembatas (hanya berfungsi dengan beberapa jenis CSV, dengan tanda kutip dan koma yang disematkan).
sed ":a;s/\(^\/[^0-9.]\)\(\+\)\(\(3\)\)/\1\2,\3/g;ta" file .txt Mengubah format angka di file.txt dari 1234.56 menjadi 1.234.56
sed -r "s/\<(reg/exp)+/\U&/g" Mengonversi kata apa pun yang dimulai dengan reg atau exp menjadi huruf besar.
sed "1.20s/Johnson/White/g" file.txt Mengubah Johnson menjadi Putih hanya pada baris 1 - 20.
sed "1,20 !s/Johnson/White/g" file.txt Contoh sebelumnya dibalik (menggantikan semuanya kecuali baris 1-20)
sed "/dari/,/sampai/ ( s/\ /magenta/g; \ s/\ /cyan/g; )" file.txt Mengganti hanya antara "dari" dan "sampai"
sed "/ENDNOTES:/,$ ( s/Schaff/Herzog/g; \ s/Kraft/Ebbing/g; )" file.txt Menggantikan hanya dari kata "ENDNOTES:" sampai EOF
sed "/./(H;$!d;);x;/regex/!d" file.txt Mencetak paragraf hanya jika berisi regex
sed -e "/./(H;$!d;)" -e "x;/RE1/!d;/RE2/!d;/RE3/!d" file.txt Cetak paragraf hanya jika mengandung RE1, RE2 dan RE3
sed "s/14"/empat belas inci/g" file.txt Ini adalah bagaimana Anda dapat menggunakan tanda kutip ganda
sed "s/\/some\/UNIX\/path/\/a\/new\/path/g" file.txt Bekerja dengan Unix Paths
sed "s///g" file.txt Menghapus semua karakter yang dimulai dengan a dan diakhiri dengan g dari file file.txt
sed "s/\(.*\)foo/\1bar/" file.txt Menggantikan hanya pertandingan terakhir foo dengan bar
sed "1!G;h;$!d" Mengganti Perintah tac
sed "/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//" Mengganti perintah rev
sed 10q file.txt Mengganti perintah kepala
sed -e:a -e "$q;N;11,$D;ba" \ file.txt Mengganti perintah ekor
sed "$!N; /^\(.*\)\n\1$/!P; D" \ file.txt Mengganti Perintah uniq
sed "$!N; s/^\(.*\)\n\1$/\1/;\ t; D" file.txt Perintah terbalik (setara dengan uniq -d)
sed "$!N;$!D" file.txt Setara dengan ekor -n 2
sed -n "$p" file.txt ... ekor -n 1 (atau ekor -1)
sed "/regexp/!d" file.txt setara grep
sed -n "/regexp/(g;1!p;);h" file.txt Mencetak baris yang muncul sebelum kecocokan pertama dari ekspresi reguler, tetapi tidak menyertakan kecocokan itu sendiri.
sed -n "/regexp/(n;p;)" file.txt Mencetak baris setelah kecocokan pertama dari ekspresi reguler, tetapi tidak termasuk kecocokan itu sendiri.
sed "/pattern/d" file.txt Menghapus pola pencocokan garis
sed "/./!d" file.txt Menghapus semua baris kosong dari file
sed "/^$/N;/\n$/N;//D" file.txt Menghapus semua baris kosong berurutan kecuali dua baris pertama
sed -n "/^$/(p;h;);/./(x;/./p;)"\ file.txt Menghapus baris terakhir dari setiap paragraf
sed "/^$/q" Mendapatkan tajuk email
sed "1,/^$/d" Mendapat isi pesan
sed "/^Subjek: */!d; s///;q" Mendapatkan subjek email
sed "s/^/> /" Mengutip pesan dengan menyisipkan "> " sebelum setiap baris
sed "s/^> //" Perintah terbalik (menghapus kutipan dari pesan)
sed -e:a -e "s/<[^>]**>//g;/ Menghapus tag HTML
sed "/./(H;d;);x;s/\n/=(NL)=/g" file.txt / sort \ / sed "1s/=(NL)=//;s/=( NL)=/\n/g" Mengurutkan paragraf dalam file.txt menurut abjad
sed" [dilindungi email]/usr/ [dilindungi email]&/[dilindungi email]"path.txt Mengganti /usr/bin dengan /usr/bin/local di path.txt
sed" [dilindungi email]^.*[dilindungi email]<<<&>>>@g"path.txt Cobalah dan lihat :)
sed "s/\(\/[^:]*\).*/\1/g" path.txt Asalkan path.txt berisi $PATH, hanya mencetak jalur pertama pada setiap baris
sed "s/\([^:]*\).*/\1/" /etc/passwd penggantian awk - hanya tampilkan pengguna dari file passwd
echo "Selamat Datang Di Barang Geek" / sed \ "s/\(\b\)/\(\1\)/g" (W)selamat datang (T)o (T)he (G)eek (S)tuff Dapat dimengerti tanpa penjelasan
sed -e "/^$/,/^END/s/hills/\ pegunungan/g" file.txt Menggantikan "bukit" dengan "pegunungan", tetapi hanya dalam blok teks yang dimulai dengan baris kosong dan diakhiri dengan baris dengan tiga karakter "AKHIR", inklusif.
sed -e "/^#/d" /etc/services/more Menampilkan file layanan tanpa baris komentar
sed" [dilindungi email]\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\[dilindungi email]"path.txt Membalik urutan elemen di baris terakhir file path.txt
sed "/regex/(x;p;x;)" file.txt Sisipan garis baru di atas setiap baris yang cocok dengan ekspresi reguler
sed "/AAA/!d; /BBB/!d; /CCC/!d" file.txt Mencari AAA, BBB, dan CCC dalam urutan apa pun
sed "/AAA.*BBB.*CCC/!d" file.txt Mencari AAA, BBB dan CCC dalam urutan yang diberikan
sed -n "/^.\(65\)/p" file.txt Mencetak baris 65 karakter atau lebih
sed -n "/^.\(65\)/!p" file.txt Mencetak baris 65 karakter atau kurang
sed "/regex/G" file.txt Menyisipkan baris kosong di bawah setiap baris
sed "/regex/(x;p;x;G;)" file.txt Menyisipkan baris kosong di atas dan di bawah setiap baris
sed = file.txt / sed "N;s/\n/\t/" Baris angka di file.txt
sed -e:a -e "s/^.\(1,78\)$/ &/;ta" file.txt Ratakan teks ke kanan
sed -e:a -e "s/^.\(1,77\)$/ &/;ta" -e "s/\(*\)\1/\1/" file.txt Ratakan teks ke tengah

6. Kesimpulan

Ini hanya sebagian dari apa yang dapat dikatakan tentang sed, tetapi rangkaian artikel ini lebih merupakan panduan cara yang kami harap akan membantu Anda menghargai kekuatan penuh utilitas Unix dan membuat pekerjaan Anda lebih efisien.

Terakhir kali kita berbicara tentang fungsi dalam skrip bash, khususnya cara memanggilnya dari garis komando. Topik kita hari ini sangat alat yang berguna untuk memproses data string - Utilitas Linux, yang disebut sed. Ini sering digunakan untuk bekerja dengan teks yang terlihat seperti file log, file konfigurasi, dan file lainnya.



Jika Anda menangani data dalam beberapa cara dalam skrip bash, Anda harus terbiasa dengan alat sed dan gawk. Di sini kita akan fokus pada sed dan bekerja dengan teks, karena ini sangat langkah penting dalam perjalanan kami melalui pengembangan skrip bash yang luas.

Sekarang kita akan menganalisis dasar-dasar bekerja dengan sed, serta melihat lebih dari tiga lusin contoh penggunaan alat ini.

dasar-dasar sed

Utilitas sed disebut editor teks aliran. Editor teks interaktif seperti nano bekerja dengan teks menggunakan keyboard, mengedit file, menambahkan, menghapus, atau mengubah teks. Sed memungkinkan Anda untuk mengedit aliran data berdasarkan seperangkat aturan yang ditentukan oleh pengembang. Berikut skema pemanggilan perintah ini:

$ sed file opsi
Secara default, sed menerapkan aturan yang ditentukan saat dipanggil, dinyatakan sebagai serangkaian perintah, ke STDIN . Hal ini memungkinkan data untuk diteruskan langsung ke sed.

Misalnya seperti ini:

$ echo "Ini adalah ujian" | sed "s/tes/tes lain/"
Inilah yang terjadi ketika Anda menjalankan perintah ini.


Contoh panggilan sed sederhana

Dalam hal ini, sed mengganti kata "test" dalam string yang diteruskan untuk diproses dengan kata-kata "another test". Garis miring digunakan untuk memformat aturan untuk memproses teks yang diapit tanda kutip. Dalam kasus kami, perintah seperti s/pattern1/pattern2/ digunakan. Huruf "s" adalah singkatan dari kata "pengganti", yaitu kami memiliki tim pengganti. Sed, menjalankan perintah ini, akan melihat teks yang ditransfer dan mengganti fragmen yang ditemukan di dalamnya (kita akan membicarakan yang mana, akan kita bicarakan di bawah), sesuai dengan pattern1 , dengan pattern2 .

Di atas adalah contoh primitif menggunakan sed, hanya untuk membantu Anda memulai. Faktanya, sed dapat digunakan dalam skenario pengolah kata yang jauh lebih kompleks, seperti bekerja dengan file.

Di bawah ini adalah file yang berisi potongan teks, dan hasil pemrosesannya dengan perintah ini:

$ sed "s/test/test lain" ./myfile


File teks dan hasil pengolahannya

Di sini pendekatan yang sama seperti yang kami gunakan di atas diterapkan, tetapi sekarang sed memproses teks yang disimpan dalam file. Namun, jika file cukup besar, Anda akan melihat bahwa sed memproses data dalam potongan dan menampilkan apa yang diproses di layar, tanpa menunggu seluruh file diproses.

Sed tidak mengubah data dalam file yang sedang diproses. Editor membaca file, memproses apa yang dibacanya, dan mengirimkan output ke STDOUT . Untuk memastikan bahwa file sumber tidak berubah, cukup, setelah diteruskan ke sed, untuk membukanya. Jika perlu, output sed dapat diarahkan ke file, mungkin menimpa file lama. Jika Anda sudah familiar dengan salah satu artikel sebelumnya dalam seri ini, yang berhubungan dengan mengarahkan aliran input dan output, Anda harus dapat melakukan ini.

Menjalankan set perintah saat memanggil sed

Untuk melakukan beberapa operasi pada data, gunakan opsi -e saat memanggil sed. Misalnya, berikut ini cara mengatur penggantian dua bagian teks:

$ sed -e "s/This/That/; s/test/another test/" ./myfile


Menggunakan sakelar -e saat memanggil sed

Kedua perintah diterapkan ke setiap baris teks dari file. Mereka harus dipisahkan oleh titik koma, dan tidak boleh ada spasi antara akhir perintah dan titik koma.
Untuk memasukkan beberapa pola pemrosesan teks saat memanggil sed, Anda dapat, setelah memasukkan kutipan tunggal pertama, tekan Enter, lalu masukkan setiap aturan pada baris baru, tanpa melupakan kutipan penutup:

$ sed -e "> s/This/That/ > s/test/another test/" ./myfile
Inilah yang terjadi setelah perintah, yang disajikan dalam formulir ini, dijalankan.


Cara lain untuk bekerja dengan sed

Membaca perintah dari file

Jika ada banyak perintah sed untuk memproses teks, biasanya yang terbaik adalah menuliskannya ke file terlebih dahulu. Untuk memberi tahu sed file yang berisi perintah, gunakan sakelar -f:

Berikut adalah isi dari file mycommands:

S/Ini/Itu/s/tes/tes lain/
Mari kita panggil sed, memberikan editor file dengan perintah dan file untuk diproses:

$ sed -f mycommands myfile
Hasil pemanggilan perintah seperti itu mirip dengan yang diperoleh pada contoh sebelumnya.


Menggunakan file dengan perintah saat memanggil sed

Ganti bendera perintah

Perhatikan baik-baik contoh berikut.

$ sed "s/test/test lain/" myfile
Inilah yang ada di dalam file, dan apa yang akan dihasilkan ketika sed memprosesnya.


File sumber dan hasil pemrosesannya

Perintah replace biasanya memproses file yang terdiri dari beberapa baris, tetapi hanya kemunculan pertama dari potongan teks yang dicari pada setiap baris yang diganti. Untuk mengganti semua kemunculan suatu pola, bendera yang sesuai harus digunakan.

Sintaks untuk menulis perintah pengganti saat menggunakan flag terlihat seperti ini:

S/pola/penggantian/bendera
Eksekusi perintah ini dapat dimodifikasi dengan beberapa cara.

  • Saat melewati nomor, nomor seri kemunculan templat dalam string diperhitungkan, kemunculan ini akan diganti.
  • Bendera g menunjukkan bahwa semua kemunculan pola dalam string harus diproses.
  • Bendera p menunjukkan bahwa konten string asli harus dikeluarkan.
  • Bendera file w memberi tahu perintah untuk menulis hasil pemrosesan teks ke file.
Pertimbangkan penggunaan varian pertama dari perintah ganti, yang menunjukkan posisi kemunculan yang diganti dari fragmen yang diinginkan:

$ sed "s/test/another test/2" myfile

Memanggil perintah ganti yang menentukan posisi fragmen yang akan diganti

Di sini kami menetapkan nomor 2 sebagai bendera pengganti.Hal ini menyebabkan fakta bahwa hanya kemunculan kedua dari pola yang diinginkan di setiap baris yang diganti. Sekarang mari kita coba flag pengganti global - g:

$ sed "s/test/another test/g" myfile
Seperti yang Anda lihat dari output, perintah ini menggantikan semua kemunculan pola dalam teks.


Penggantian Global

Bendera perintah substitusi p memungkinkan output dari baris yang cocok, sedangkan opsi -n yang ditentukan saat menjalankan sed menekan output normal:

$ sed -n "s/test/another test/p" myfile
Akibatnya, ketika sed dijalankan dalam konfigurasi ini, hanya baris (dalam kasus kami, satu baris) di mana potongan teks tertentu ditemukan yang ditampilkan di layar.


Menggunakan perintah substitusi flag p

Mari gunakan flag w, yang memungkinkan Anda menyimpan hasil pemrosesan teks ke file:

$ sed "s/test/test lain/w output" myfile


Menyimpan hasil pemrosesan teks ke file

Terlihat jelas bahwa selama pengoperasian perintah, data dikeluarkan ke STDOUT , sedangkan baris yang diproses ditulis ke file yang namanya ditentukan setelah w .

Karakter pembatas

Bayangkan mengganti /bin/bash dengan /bin/csh di /etc/passwd . Tugasnya tidak begitu sulit:

$ sed "s/\/bin\/bash/\/bin\/csh/" /etc/passwd
Namun, itu tidak terlihat sangat bagus. Masalahnya adalah karena garis miring digunakan sebagai karakter pemisah, karakter yang sama di baris yang diteruskan ke sed harus diloloskan. Akibatnya, keterbacaan perintah menderita.

Untungnya, sed memungkinkan kita untuk mengatur karakter pembatas sendiri untuk digunakan dalam perintah penggantian. Pembatas adalah karakter pertama yang muncul setelah s:

$ sed "s!/bin/bash!/bin/csh!" /etc/passwd
Dalam hal ini, pembatasnya adalah Tanda seru, menghasilkan kode yang lebih mudah dibaca dan terlihat lebih bersih dari sebelumnya.

Memilih fragmen teks untuk diproses

Sejauh ini, kami telah memanggil sed untuk memproses semua yang diteruskan ke editor. Dalam beberapa kasus, hanya sebagian teks yang perlu diproses dengan sed - beberapa baris atau kelompok baris tertentu. Ada dua pendekatan untuk mencapai tujuan ini:
  • Tetapkan batas jumlah baris yang diproses.
  • Tentukan filter yang cocok dengan baris yang ingin Anda proses.
Mari kita pertimbangkan pendekatan pertama. Ada dua kemungkinan pilihan di sini. Yang pertama, dibahas di bawah, menyediakan untuk menentukan jumlah satu baris yang akan diproses:

$ sed "2s/tes/tes lain/" file saya


Memproses hanya satu baris, nomor yang diberikan saat menelepon sed

Opsi kedua adalah rentang string:

$ sed "2,3s/test/test lain/" myfile


Penanganan Rentang Baris

Selain itu, Anda dapat memanggil perintah ganti sehingga file diproses dari baris tertentu hingga akhir:

$ sed "2,$s/test/another test/" myfile


Memproses file dari baris kedua hingga akhir

Untuk memproses hanya baris yang cocok dengan filter yang ditentukan menggunakan perintah ganti, perintah harus dipanggil seperti ini:

$ sed "/likegeeks/s/bash/csh/" /etc/passwd
Dengan analogi dengan apa yang dibahas di atas, template dilewatkan sebelum nama perintah s .


Memproses Baris yang Cocok dengan Filter

Di sini kami menggunakan filter yang sangat sederhana. Untuk mengambil keuntungan penuh dari kemungkinan pendekatan ini Anda dapat menggunakan ekspresi reguler. Kami akan membicarakannya di salah satu artikel berikut dalam seri ini.

Menghapus baris

Utilitas sed bagus untuk lebih dari sekadar mengganti urutan karakter dalam string dengan yang lain. Dengan bantuannya, yaitu, menggunakan perintah d, Anda dapat menghapus baris dari aliran teks.

Panggilan perintah terlihat seperti ini:

$ sed "3d" file saya
Kami ingin baris ketiga dihapus dari teks. Perhatikan bahwa ini bukan file. File akan tetap tidak berubah, penghapusan hanya akan mempengaruhi output yang dihasilkan oleh sed.


Menghapus baris ketiga

Jika Anda tidak menentukan nomor baris yang akan dihapus saat memanggil perintah d, semua baris dalam aliran akan dihapus.

Berikut cara menerapkan perintah d ke berbagai baris:

$ sed "2,3d" file saya


Menghapus Rentang Baris

Dan inilah cara menghapus baris, mulai dari yang diberikan - dan hingga akhir file:

$ sed "3,$d" file saya


Hapus baris ke akhir file

Baris juga dapat dihapus sesuai dengan pola:

$ sed "/test/d" file saya


Menghapus string berdasarkan pola

Saat memanggil d, Anda dapat menentukan beberapa pola - garis di mana pola itu muncul, dan garis-garis yang ada di antaranya, akan dihapus:

$ sed "/detik/,/keempat/d" file saya


Menghapus Rentang Baris Menggunakan Pola

Memasukkan teks ke dalam aliran

Dengan sed, Anda dapat memasukkan data ke dalam aliran teks menggunakan perintah i dan a:
  • Perintah i menambahkan baris baru sebelum yang diberikan.
  • Perintah a menambahkan baris baru setelah yang diberikan.
Pertimbangkan contoh menggunakan perintah i:

$ echo "Tes lain" | sed "i\Tes pertama"


tim saya

Sekarang mari kita lihat perintah a:

$ echo "Tes lain" | sed "a\Tes pertama"


tim a

Seperti yang Anda lihat, perintah ini menambahkan teks sebelum atau sesudah data dari aliran. Bagaimana jika Anda perlu menambahkan garis di suatu tempat di tengah?

Di sini kita akan dibantu dengan menentukan jumlah garis referensi dalam aliran, atau template. Perhatikan bahwa menangani string sebagai rentang tidak akan berfungsi di sini. Mari kita panggil perintah i, tentukan nomor baris sebelum kita ingin menyisipkan baris baru:

$ sed "2i\Ini adalah baris yang dimasukkan." file saya


saya perintah dengan nomor baris referensi

Mari kita lakukan hal yang sama dengan perintah:

$ sed "2a\Ini adalah baris yang ditambahkan." file saya


Perintah a dengan nomor baris referensi

Perhatikan perbedaan cara kerja perintah i dan a. Yang pertama memasukkan baris baru sebelum yang ditentukan, yang kedua - setelahnya.

Penggantian tali

Perintah c memungkinkan Anda untuk mengubah konten seluruh baris teks dalam aliran data. Saat memanggilnya, Anda perlu menentukan nomor baris, alih-alih data baru mana yang harus ditambahkan ke aliran:

$ sed "3c\Ini adalah baris yang dimodifikasi." file saya


Mengganti seluruh string

Jika Anda menggunakan templat dalam formulir saat memanggil perintah teks biasa atau ekspresi reguler, semua string yang cocok dengan pola akan diganti:

$ sed "/Ini adalah/c Ini adalah baris teks yang diubah." file saya


Mengganti string dengan pola

Substitusi karakter

Perintah y beroperasi pada karakter individual, menggantinya sesuai dengan data yang diteruskan ke sana saat dipanggil:

$ sed "y/123/567/" file saya


Substitusi karakter

Saat menggunakan perintah ini, Anda perlu mempertimbangkan bahwa itu berlaku untuk seluruh aliran teks, Anda tidak dapat membatasinya pada kemunculan karakter tertentu.

Menampilkan nomor baris

Jika Anda memanggil sed menggunakan perintah =, utilitas akan mencetak nomor baris dalam aliran data:

$ sed "=" file saya


Menampilkan nomor baris

Editor aliran mengeluarkan nomor baris sebelum isinya.

Jika Anda meneruskan pola ke perintah ini dan menggunakan opsi sed -n, hanya nomor baris yang cocok dengan pola yang akan dicetak:

$ sed -n "/test/=" file saya


Tampilkan nomor baris yang cocok dengan pola

Membaca data yang akan dimasukkan dari file

Di atas, kami melihat teknik untuk memasukkan data ke dalam aliran, menunjukkan apa yang harus dimasukkan, tepat saat memanggil sed. Anda juga dapat menggunakan file sebagai sumber data. Untuk melakukan ini, gunakan perintah r, yang memungkinkan Anda untuk memasukkan data dari file yang ditentukan ke dalam aliran. Saat memanggilnya, Anda dapat menentukan nomor baris yang setelahnya Anda ingin menyisipkan konten file, atau templat.

Pertimbangkan sebuah contoh:

$ sed "3r file baru" file saya


Memasukkan Konten File ke dalam Aliran

Di sini konten file baru telah dimasukkan setelah baris ketiga file saya.

Inilah yang terjadi jika Anda menggunakan templat saat memanggil perintah r:

$ sed "/test/r file baru" file saya


Menggunakan wildcard saat menjalankan perintah r

Isi file akan disisipkan setelah setiap baris yang cocok dengan pola.

Contoh

Mari kita bayangkan tugas seperti itu. Ada sebuah file yang di dalamnya terdapat urutan karakter tertentu, dengan sendirinya tidak berarti, yang harus diganti dengan data yang diambil dari file lain. Yaitu, biarkan itu menjadi file newfile , di mana urutan karakter DATA memainkan peran sebagai pengganti. Data yang akan diganti DATA disimpan dalam file data.

Anda dapat mengatasi masalah ini menggunakan perintah r dan d dari editor aliran sed:

$ Sed "/DATA>/ ( r file baru d)" file saya


Mengganti placeholder dengan data nyata

Seperti yang Anda lihat, alih-alih placeholder DATA, sed menambahkan dua baris dari file data ke aliran output.

Hasil

Hari ini kami membahas dasar-dasar bekerja dengan editor sed stream. Faktanya, sed adalah topik besar. Mempelajarinya dapat dibandingkan dengan mempelajari bahasa pemrograman baru, tetapi begitu Anda memahami dasar-dasarnya, Anda dapat menguasai sed ke tingkat mana pun yang Anda butuhkan. Akibatnya, kemampuan Anda untuk memproses teks dengannya hanya akan dibatasi oleh imajinasi Anda.

Itu saja untuk hari ini. Lain kali kita akan berbicara tentang bahasa pemrosesan data awk.

Pembaca yang budiman! Apakah Anda menggunakan sed dalam pekerjaan sehari-hari Anda? Jika ya, silakan bagikan pengalaman Anda.

Banyak dari Anda mungkin telah menggunakan streaming editor teks sed untuk beberapa tujuan saya, jika tidak, saya akan dengan senang hati memberi tahu Anda tentang itu, saya akan mencoba lebih detail. Kenapa disebut streaming? Jawabannya sederhana - bayangkan sebuah masukan Dokumen Teks yang melewati program dan berakhir dengan beberapa bentuk lain file yang diberikan diproses oleh program. Semacam penggiling daging - Anda memasukkan daging, berdasarkan kisi - Anda mendapatkan daging cincang atau yang lainnya.

Jadi, secara default, sepertinya utilitas ini sudah ada di sistem Anda (dalam kasus saya, saya sudah memilikinya di Debian 7.6), jika tidak, maka -

Dengan teks:

parameter "s" di awal menunjukkan bahwa Anda perlu mengganti teks, g - di akhir teks yang diganti - bahwa Anda perlu melakukan ini secara global (di seluruh file)

Misalnya, kami ingin mengganti kata Sergey dengan Andrey di file text.txt kami dan mengunggah semua ini ke file textout.txt, kami bertindak:

sed "s/Sergey/Andrey/g" teks . txt > keluar teks. txt

Hasil:

Jika Anda ingin membuat substitusi untuk Simbol khusus- misalnya, pada simbol &, perlu sebelum khusus. letakkan garis miring terbalik "\" dengan karakter, jika Anda perlu menentukan apa yang perlu dibalikkan ke awal baris, karakter khusus "^" digunakan. Selain itu, dalam satu baris Anda dapat menulis 2 atau lebih perubahan dengan memisahkannya dengan titik koma - ";". Misalnya, kami menyiksa file textout.txt yang sudah diubah. Pertama, saya akan menampilkan konten file textout.txt saat ini lagi:

root @ testhostname : ~ # cat textout.txt

Tes untuk Andrey

Tes 2 untuk Andrey

Tes 3 untuk Andrey

Sekarang masukkan perintah:

sed "s/for/\&/g;s/^Test/Sergey/g" textout . txt > textout2 . txt

Jadi, alih-alih kata untuk, kita meletakkan ikon & (karakter khusus dimasukkan dengan simbol "\" sebelum karakter khusus), lalu tanda pemisah (untuk menulis semua perubahan dalam satu baris sed'a -> " ;", alih-alih kata di awal baris "Tes", letakkan kata Sergey, hasil dari apa yang terjadi:

Semuanya seperti yang kami inginkan!

Jadi, sed adalah penolong yang baik saat melihat log. Misalnya, kita perlu mengunggah semua baris tanggal hari ini (dalam kasus kita 10 Oktober) dari file log /var/log/messages ke file testlog.txt, mari kita lanjutkan:

sed - n "/^Oct 10/ p" / var / log / pesan > testlog . txt

di sini kita telah menambahkan parameter -n, dan kemudian - '/^Oct 10/ - artinya baris harus dimulai dari tanggal 10 Oktober, lalu parameter p - artinya print (mencetak konten dalam kondisi ini), lalu sumbernya file dan file tempat kita membuang hasilnya sesuai dengan kondisi filter kita, jalankan, lihat apa isi file testlog.txt hanya pada 10 Oktober:

Bagus sekali! Jika banyak baris tidak diperlukan, tetapi dengan syarat ada kebutuhan untuk mengambil hanya dari baris pertama hingga baris kelima, kami memisahkan permintaan kami saat ini dengan tanda "|" menghapus unggahan ke file testlog.txt dan menulis sed -n 1.5p - yang berarti bahwa kita perlu mengeluarkan (p - mencetak di akhir ekspresi) dari "1" pertama hingga (dipisahkan koma) "5" kelima " garis. Secara total, kami mendapatkan sesuatu seperti ini:

sed - n "/^10 Oktober/ p" / var / log / pesan | sed - n 1 , 5p > testlog - 5strok.txt

Sekali lagi, saya menarik perhatian Anda pada fakta bahwa file tempat kami mengunggah hasil telah dipindahkan ke akhir (testlog-5strok.txt), kami melihat hasil dari tindakan kami:

Terakhir kali kita berbicara tentang fungsi dalam skrip bash, khususnya cara memanggilnya dari baris perintah. Topik kita hari ini adalah alat yang sangat berguna untuk memproses data string - utilitas Linux yang disebut sed. Ini sering digunakan untuk bekerja dengan teks yang terlihat seperti file log, file konfigurasi, dan file lainnya.



Jika Anda menangani data dalam beberapa cara dalam skrip bash, Anda harus terbiasa dengan alat sed dan gawk. Di sini kita akan fokus pada sed dan bekerja dengan teks, karena ini adalah langkah yang sangat penting dalam perjalanan kita melalui pengembangan skrip bash yang luas.

Sekarang kita akan menganalisis dasar-dasar bekerja dengan sed, serta melihat lebih dari tiga lusin contoh penggunaan alat ini.

dasar-dasar sed

Utilitas sed disebut editor teks aliran. Editor teks interaktif seperti nano bekerja dengan teks menggunakan keyboard, mengedit file, menambahkan, menghapus, atau mengubah teks. Sed memungkinkan Anda untuk mengedit aliran data berdasarkan seperangkat aturan yang ditentukan oleh pengembang. Berikut skema pemanggilan perintah ini:

$ sed file opsi
Secara default, sed menerapkan aturan yang ditentukan saat dipanggil, dinyatakan sebagai serangkaian perintah, ke STDIN . Hal ini memungkinkan data untuk diteruskan langsung ke sed.

Misalnya seperti ini:

$ echo "Ini adalah ujian" | sed "s/tes/tes lain/"
Inilah yang terjadi ketika Anda menjalankan perintah ini.


Contoh panggilan sed sederhana

Dalam hal ini, sed mengganti kata "test" dalam string yang diteruskan untuk diproses dengan kata-kata "another test". Garis miring digunakan untuk memformat aturan untuk memproses teks yang diapit tanda kutip. Dalam kasus kami, perintah seperti s/pattern1/pattern2/ digunakan. Huruf "s" adalah singkatan dari kata "pengganti", yaitu kami memiliki tim pengganti. Sed, menjalankan perintah ini, akan melihat teks yang ditransfer dan mengganti fragmen yang ditemukan di dalamnya (kita akan membicarakan yang mana, akan kita bicarakan di bawah), sesuai dengan pattern1 , dengan pattern2 .

Di atas adalah contoh primitif menggunakan sed, hanya untuk membantu Anda memulai. Faktanya, sed dapat digunakan dalam skenario pengolah kata yang jauh lebih kompleks, seperti bekerja dengan file.

Di bawah ini adalah file yang berisi potongan teks, dan hasil pemrosesannya dengan perintah ini:

$ sed "s/test/test lain" ./myfile


File teks dan hasil pemrosesannya

Di sini pendekatan yang sama seperti yang kami gunakan di atas diterapkan, tetapi sekarang sed memproses teks yang disimpan dalam file. Namun, jika file cukup besar, Anda akan melihat bahwa sed memproses data dalam potongan dan menampilkan apa yang diproses di layar, tanpa menunggu seluruh file diproses.

Sed tidak mengubah data dalam file yang sedang diproses. Editor membaca file, memproses apa yang dibacanya, dan mengirimkan output ke STDOUT . Untuk memastikan bahwa file sumber tidak berubah, cukup, setelah diteruskan ke sed, untuk membukanya. Jika perlu, output sed dapat diarahkan ke file, mungkin menimpa file lama. Jika Anda sudah familiar dengan salah satu yang sebelumnya dalam seri ini, yang berhubungan dengan mengarahkan aliran input dan output, Anda harus dapat melakukan ini.

Menjalankan set perintah saat memanggil sed

Untuk melakukan beberapa operasi pada data, gunakan opsi -e saat memanggil sed. Misalnya, berikut ini cara mengatur penggantian dua bagian teks:

$ sed -e "s/This/That/; s/test/another test/" ./myfile


Menggunakan sakelar -e saat memanggil sed

Kedua perintah diterapkan ke setiap baris teks dari file. Mereka harus dipisahkan oleh titik koma, dan tidak boleh ada spasi antara akhir perintah dan titik koma.
Untuk memasukkan beberapa pola pemrosesan teks saat memanggil sed, Anda dapat, setelah memasukkan kutipan tunggal pertama, tekan Enter, lalu masukkan setiap aturan pada baris baru, tanpa melupakan kutipan penutup:

$ sed -e "> s/This/That/ > s/test/another test/" ./myfile
Inilah yang terjadi setelah perintah, yang disajikan dalam formulir ini, dijalankan.


Cara lain untuk bekerja dengan sed

Membaca perintah dari file

Jika ada banyak perintah sed untuk memproses teks, biasanya yang terbaik adalah menuliskannya ke file terlebih dahulu. Untuk memberi tahu sed file yang berisi perintah, gunakan sakelar -f:

Berikut adalah isi dari file mycommands:

S/Ini/Itu/s/tes/tes lain/
Mari kita panggil sed, memberikan editor file dengan perintah dan file untuk diproses:

$ sed -f mycommands myfile
Hasil pemanggilan perintah seperti itu mirip dengan yang diperoleh pada contoh sebelumnya.


Menggunakan file dengan perintah saat memanggil sed

Ganti bendera perintah

Perhatikan baik-baik contoh berikut.

$ sed "s/test/test lain/" myfile
Inilah yang ada di dalam file, dan apa yang akan dihasilkan ketika sed memprosesnya.


File sumber dan hasil pemrosesannya

Perintah replace biasanya memproses file yang terdiri dari beberapa baris, tetapi hanya kemunculan pertama dari potongan teks yang dicari pada setiap baris yang diganti. Untuk mengganti semua kemunculan suatu pola, bendera yang sesuai harus digunakan.

Sintaks untuk menulis perintah pengganti saat menggunakan flag terlihat seperti ini:

S/pola/penggantian/bendera
Eksekusi perintah ini dapat dimodifikasi dengan beberapa cara.

  • Saat melewati nomor, nomor seri kemunculan templat dalam string diperhitungkan, kemunculan ini akan diganti.
  • Bendera g menunjukkan bahwa semua kemunculan pola dalam string harus diproses.
  • Bendera p menunjukkan bahwa konten string asli harus dikeluarkan.
  • Bendera file w memberi tahu perintah untuk menulis hasil pemrosesan teks ke file.
Pertimbangkan penggunaan varian pertama dari perintah ganti, yang menunjukkan posisi kemunculan yang diganti dari fragmen yang diinginkan:

$ sed "s/test/another test/2" myfile

Memanggil perintah ganti yang menentukan posisi fragmen yang akan diganti

Di sini kami menetapkan nomor 2 sebagai bendera pengganti.Hal ini menyebabkan fakta bahwa hanya kemunculan kedua dari pola yang diinginkan di setiap baris yang diganti. Sekarang mari kita coba flag pengganti global - g:

$ sed "s/test/another test/g" myfile
Seperti yang Anda lihat dari output, perintah ini menggantikan semua kemunculan pola dalam teks.


Penggantian Global

Bendera perintah substitusi p memungkinkan output dari baris yang cocok, sedangkan opsi -n yang ditentukan saat menjalankan sed menekan output normal:

$ sed -n "s/test/another test/p" myfile
Akibatnya, ketika sed dijalankan dalam konfigurasi ini, hanya baris (dalam kasus kami, satu baris) di mana potongan teks tertentu ditemukan yang ditampilkan di layar.


Menggunakan perintah substitusi flag p

Mari gunakan flag w, yang memungkinkan Anda menyimpan hasil pemrosesan teks ke file:

$ sed "s/test/test lain/w output" myfile


Menyimpan hasil pemrosesan teks ke file

Jelas terlihat bahwa selama pengoperasian perintah, data dikeluarkan ke , sedangkan baris yang diproses ditulis ke file yang namanya ditentukan setelah w .

Karakter pembatas

Bayangkan mengganti /bin/bash dengan /bin/csh di /etc/passwd . Tugasnya tidak begitu sulit:

$ sed "s/\/bin\/bash/\/bin\/csh/" /etc/passwd
Namun, itu tidak terlihat sangat bagus. Masalahnya adalah karena garis miring digunakan sebagai karakter pemisah, karakter yang sama di baris yang diteruskan ke sed harus diloloskan. Akibatnya, keterbacaan perintah menderita.

Untungnya, sed memungkinkan kita untuk mengatur karakter pembatas sendiri untuk digunakan dalam perintah penggantian. Pembatas adalah karakter pertama yang muncul setelah s:

$ sed "s!/bin/bash!/bin/csh!" /etc/passwd
Dalam hal ini, tanda seru digunakan sebagai pembatas, membuat kode lebih mudah dibaca dan lebih bersih dari sebelumnya.

Memilih fragmen teks untuk diproses

Sejauh ini, kami telah memanggil sed untuk memproses semua yang diteruskan ke editor. Dalam beberapa kasus, hanya sebagian teks yang perlu diproses dengan sed - beberapa baris atau kelompok baris tertentu. Ada dua pendekatan untuk mencapai tujuan ini:
  • Tetapkan batas jumlah baris yang diproses.
  • Tentukan filter yang cocok dengan baris yang ingin Anda proses.
Mari kita pertimbangkan pendekatan pertama. Ada dua kemungkinan pilihan di sini. Yang pertama, dibahas di bawah, menyediakan untuk menentukan jumlah satu baris yang akan diproses:

$ sed "2s/tes/tes lain/" file saya


Memproses hanya satu baris, nomor yang diberikan saat menelepon sed

Opsi kedua adalah rentang string:

$ sed "2,3s/test/test lain/" myfile


Penanganan Rentang Baris

Selain itu, Anda dapat memanggil perintah ganti sehingga file diproses dari baris tertentu hingga akhir:

$ sed "2,$s/test/another test/" myfile


Memproses file dari baris kedua hingga akhir

Untuk memproses hanya baris yang cocok dengan filter yang ditentukan menggunakan perintah ganti, perintah harus dipanggil seperti ini:

$ sed "/likegeeks/s/bash/csh/" /etc/passwd
Dengan analogi dengan apa yang dibahas di atas, template dilewatkan sebelum nama perintah s .


Memproses Baris yang Cocok dengan Filter

Di sini kami menggunakan filter yang sangat sederhana. Untuk sepenuhnya mengungkapkan kemungkinan pendekatan ini, Anda dapat menggunakan ekspresi reguler. Kami akan membicarakannya di salah satu artikel berikut dalam seri ini.

Menghapus baris

Utilitas sed bagus untuk lebih dari sekadar mengganti urutan karakter dalam string dengan yang lain. Dengan bantuannya, yaitu, menggunakan perintah d, Anda dapat menghapus baris dari aliran teks.

Panggilan perintah terlihat seperti ini:

$ sed "3d" file saya
Kami ingin baris ketiga dihapus dari teks. Perhatikan bahwa ini bukan file. File akan tetap tidak berubah, penghapusan hanya akan mempengaruhi output yang dihasilkan oleh sed.


Menghapus baris ketiga

Jika Anda tidak menentukan nomor baris yang akan dihapus saat memanggil perintah d, semua baris dalam aliran akan dihapus.

Berikut cara menerapkan perintah d ke berbagai baris:

$ sed "2,3d" file saya


Menghapus Rentang Baris

Dan inilah cara menghapus baris, mulai dari yang diberikan - dan hingga akhir file:

$ sed "3,$d" file saya


Hapus baris ke akhir file

Baris juga dapat dihapus sesuai dengan pola:

$ sed "/test/d" file saya


Menghapus string berdasarkan pola

Saat memanggil d, Anda dapat menentukan beberapa pola - garis di mana pola itu muncul, dan garis-garis yang ada di antaranya, akan dihapus:

$ sed "/detik/,/keempat/d" file saya


Menghapus Rentang Baris Menggunakan Pola

Memasukkan teks ke dalam aliran

Dengan sed, Anda dapat memasukkan data ke dalam aliran teks menggunakan perintah i dan a:
  • Perintah i menambahkan baris baru sebelum yang diberikan.
  • Perintah a menambahkan baris baru setelah yang diberikan.
Pertimbangkan contoh menggunakan perintah i:

$ echo "Tes lain" | sed "i\Tes pertama"


tim saya

Sekarang mari kita lihat perintah a:

$ echo "Tes lain" | sed "a\Tes pertama"


tim a

Seperti yang Anda lihat, perintah ini menambahkan teks sebelum atau sesudah data dari aliran. Bagaimana jika Anda perlu menambahkan garis di suatu tempat di tengah?

Di sini kita akan dibantu dengan menentukan jumlah garis referensi dalam aliran, atau template. Perhatikan bahwa menangani string sebagai rentang tidak akan berfungsi di sini. Mari kita panggil perintah i, tentukan nomor baris sebelum kita ingin menyisipkan baris baru:

$ sed "2i\Ini adalah baris yang dimasukkan." file saya


saya perintah dengan nomor baris referensi

Mari kita lakukan hal yang sama dengan perintah:

$ sed "2a\Ini adalah baris yang ditambahkan." file saya


Perintah a dengan nomor baris referensi

Perhatikan perbedaan cara kerja perintah i dan a. Yang pertama memasukkan baris baru sebelum yang ditentukan, yang kedua - setelahnya.

Penggantian tali

Perintah c memungkinkan Anda untuk mengubah konten seluruh baris teks dalam aliran data. Saat memanggilnya, Anda perlu menentukan nomor baris, alih-alih data baru mana yang harus ditambahkan ke aliran:

$ sed "3c\Ini adalah baris yang dimodifikasi." file saya


Mengganti seluruh string

Jika Anda menggunakan pola dalam bentuk teks biasa atau ekspresi reguler saat memanggil perintah, semua baris yang cocok dengan pola akan diganti:

$ sed "/Ini adalah/c Ini adalah baris teks yang diubah." file saya


Mengganti string dengan pola

Substitusi karakter

Perintah y beroperasi pada karakter individual, menggantinya sesuai dengan data yang diteruskan ke sana saat dipanggil:

$ sed "y/123/567/" file saya


Substitusi karakter

Saat menggunakan perintah ini, Anda perlu mempertimbangkan bahwa itu berlaku untuk seluruh aliran teks, Anda tidak dapat membatasinya pada kemunculan karakter tertentu.

Menampilkan nomor baris

Jika Anda memanggil sed menggunakan perintah =, utilitas akan mencetak nomor baris dalam aliran data:

$ sed "=" file saya


Menampilkan nomor baris

Editor aliran mengeluarkan nomor baris sebelum isinya.

Jika Anda meneruskan pola ke perintah ini dan menggunakan opsi sed -n, hanya nomor baris yang cocok dengan pola yang akan dicetak:

$ sed -n "/test/=" file saya


Tampilkan nomor baris yang cocok dengan pola

Membaca data yang akan dimasukkan dari file

Di atas, kami melihat teknik untuk memasukkan data ke dalam aliran, menunjukkan apa yang harus dimasukkan, tepat saat memanggil sed. Anda juga dapat menggunakan file sebagai sumber data. Untuk melakukan ini, gunakan perintah r, yang memungkinkan Anda untuk memasukkan data dari file yang ditentukan ke dalam aliran. Saat memanggilnya, Anda dapat menentukan nomor baris yang setelahnya Anda ingin menyisipkan konten file, atau templat.

Pertimbangkan sebuah contoh:

$ sed "3r file baru" file saya


Memasukkan Konten File ke dalam Aliran

Di sini konten file baru telah dimasukkan setelah baris ketiga file saya.

Inilah yang terjadi jika Anda menggunakan templat saat memanggil perintah r:

$ sed "/test/r file baru" file saya


Menggunakan wildcard saat menjalankan perintah r

Isi file akan disisipkan setelah setiap baris yang cocok dengan pola.

Contoh

Mari kita bayangkan tugas seperti itu. Ada sebuah file yang di dalamnya terdapat urutan karakter tertentu, dengan sendirinya tidak berarti, yang harus diganti dengan data yang diambil dari file lain. Yaitu, biarkan itu menjadi file newfile , di mana urutan karakter DATA memainkan peran sebagai pengganti. Data yang akan diganti DATA disimpan dalam file data.

Anda dapat mengatasi masalah ini menggunakan perintah r dan d dari editor aliran sed:

$ Sed "/DATA>/ ( r file baru d)" file saya


Mengganti placeholder dengan data nyata

Seperti yang Anda lihat, alih-alih placeholder DATA, sed menambahkan dua baris dari file data ke aliran output.

Hasil

Hari ini kami membahas dasar-dasar bekerja dengan editor sed stream. Faktanya, sed adalah topik besar. Mempelajarinya dapat dibandingkan dengan mempelajari bahasa pemrograman baru, tetapi begitu Anda memahami dasar-dasarnya, Anda dapat menguasai sed ke tingkat mana pun yang Anda butuhkan. Akibatnya, kemampuan Anda untuk memproses teks dengannya hanya akan dibatasi oleh imajinasi Anda.

Itu saja untuk hari ini. Lain kali kita akan berbicara tentang bahasa pemrosesan data awk.

Pembaca yang budiman! Apakah Anda menggunakan sed dalam pekerjaan sehari-hari Anda? Jika ya, silakan bagikan pengalaman Anda.


Pengarang: Rares Aioanei
Tanggal publikasi: 19 November 2011
Terjemahan: A. Krivoshey
Tanggal transfer: Juli 2012

Nikolai Ignatushko menguji semua perintah yang disebutkan dalam artikel ini pada GNU sed versi 4.2.1 dalam distribusi Gentoo. Tidak semua skrip bekerja dengan baik pada sed versi GNU. Tapi kasusnya menyangkut hal-hal kecil yang diperbaiki. Hanya naskah untuk mengganti bukit dengan gunung yang harus diperbaiki secara signifikan.

1. Perkenalan

Selamat datang di bagian kedua dari seri kami tentang sed, versi GNU. Ada beberapa versi sed yang tersedia pada platform yang berbeda, tetapi kami akan fokus pada GNU sed versi 4.x. Banyak dari Anda pernah mendengar tentang sed, atau sudah menggunakannya, kemungkinan besar sebagai alat pengganti. Tetapi ini hanya salah satu tujuan dari sed, dan kami akan mencoba menunjukkan kepada Anda semua aspek penggunaan utilitas ini. Namanya adalah singkatan dari "Stream EDitor" dan kata "stream" (aliran) dalam hal ini bisa berarti file, pipa, atau hanya stdin. Kami harap Anda sudah memiliki pengetahuan dasar tentang Linux, dan jika Anda telah bekerja dengan ekspresi reguler, atau setidaknya tahu apa itu, maka semuanya akan jauh lebih mudah bagi Anda. Artikel ini tidak cukup besar untuk menyertakan panduan lengkap untuk ekspresi reguler, sebagai gantinya kami akan membahas konsep dasar dan memberikan banyak contoh bagaimana menggunakan sed.

2. Instalasi

Tidak banyak yang bisa dikatakan di sini. Kemungkinan besar Anda sudah menginstal sed, seperti yang digunakan oleh berbagai skrip sistem, serta oleh pengguna Linux yang ingin meningkatkan efisiensinya. Anda dapat mengetahui versi sed mana yang telah Anda instal dengan perintah:

$ sed --versi

Di sistem saya, perintah ini menunjukkan bahwa saya telah menginstal GNU sed 4.2.1, ditambah tautan ke halaman beranda program dan informasi berguna lainnya. Paket tersebut diberi nama "sed" terlepas dari distribusinya, kecuali untuk Gentoo, di mana ia hadir secara implisit.

3. Konsep

Sebelum melangkah lebih jauh, kami pikir penting untuk fokus pada apa yang "sed" lakukan, karena "stream editor" tidak banyak bicara tentang tujuannya. sed mengambil teks sebagai input, melakukan operasi yang ditentukan pada setiap baris (kecuali ditentukan lain), dan menampilkan teks yang dimodifikasi. Operasi ini dapat menambah, menyisipkan, menghapus, atau mengganti. Ini tidak semudah kelihatannya: berhati-hatilah, ada sejumlah besar opsi dan kombinasi opsi yang dapat membuat perintah sed sangat sulit untuk dipahami. Oleh karena itu, kami menyarankan Anda mempelajari dasar-dasar ekspresi reguler untuk memahami cara kerjanya. Sebelum melanjutkan dengan panduan ini, kami ingin mengucapkan terima kasih kepada Eric Pement dan yang lainnya atas inspirasi dan apa yang telah dia lakukan untuk siapa saja yang ingin belajar dan menggunakan sed.

4. Ekspresi Reguler

Karena perintah sed (skrip) tetap menjadi misteri bagi banyak orang, kami merasa bahwa pembaca kami harus memahami konsep dasar, dan tidak menyalin dan menempelkan perintah secara membabi buta yang artinya tidak mereka pahami. Ketika seseorang ingin memahami apa itu ekspresi reguler, kata kuncinya adalah "cocok", atau lebih khusus lagi, "pola pencocokan". Misalnya, dalam laporan departemen Anda, Anda menulis nama Nick, mengacu pada arsitek jaringan. Tapi Nick pergi dan John menggantikannya, jadi sekarang Anda harus mengubah kata Nick menjadi John. Jika file laporan bernama report.txt, Anda harus menjalankan perintah berikut:

$ cat report.txt | sed "s/Nick/John/g"> report_new.txt

Secara default sed menggunakan stdout, Anda dapat menggunakan operator pengalihan output seperti yang ditunjukkan pada contoh di atas. Ini adalah contoh yang sangat sederhana, tetapi kami telah mengilustrasikan beberapa poin: kami mencari semua kecocokan dari pola "Nick" dan mengganti semuanya dengan "John". Perhatikan bahwa sed melakukan pencarian peka huruf besar-kecil, jadi berhati-hatilah dan periksa file keluaran untuk memastikan semua penggantian telah dilakukan. Contoh di atas juga dapat ditulis seperti ini:

$ sed "s/Nick/John/g" report.txt > report_new.txt

Oke, katamu, tapi di mana ekspresi reguler di sini? Ya, kami ingin menunjukkan contoh dulu, dan sekarang bagian yang paling menarik dimulai.
Jika Anda tidak yakin apakah Anda menulis "nick" atau "Nick" dan ingin membahas kedua kasus tersebut, Anda harus menggunakan perintah sed "s/Nick|nick/John/g". Bilah vertikal memiliki arti yang harus Anda ketahui jika Anda mempelajari C, artinya ekspresi Anda akan cocok dengan "nick" atau "Nick". Seperti yang akan Anda lihat di bawah, saluran dapat digunakan dengan cara lain, tetapi artinya sama. Operator lain yang biasa digunakan dalam ekspresi reguler adalah "?" yang cocok dengan nol atau satu pengulangan karakter sebelumnya (yaitu flavou?r akan cocok dengan rasa dan rasa), "*" nol kali atau lebih, "+" satu kali atau lebih. "^" cocok dengan awal baris, dan "$" sebaliknya. Jika Anda adalah pengguna vi atau vim, banyak hal akan tampak akrab bagi Anda. Bagaimanapun, utilitas ini, bersama dengan awk dan C, berakar pada hari-hari awal UNIX. Kami tidak akan membicarakan ini lagi, karena lebih mudah untuk memahami arti dari karakter ini dengan contoh, tetapi Anda harus menyadari bahwa ada berbagai implementasi ekspresi reguler: POSIX, POSIX Extended, Perl, dan berbagai implementasi ekspresi reguler fuzzy , menjamin Anda sakit kepala .

5. Contoh penggunaan sed

Sintaks perintah Keterangan

Sed "s/Nick/John/g" report.txt

Menggantikan setiap kemunculan Nick dengan John di report.txt

Sed "s/Nick\|nick/John/g" report.txt

Menggantikan setiap kemunculan Nick atau nick dengan John.

Sed "s/^/ /" file.txt > file_new.txt

Menambahkan 8 spasi di sebelah kiri teks untuk meningkatkan kualitas cetak.

Sed -n "/Tentu saja/,/perhatian yang kamu bayar/p" myfile

Mencetak semua paragraf yang dimulai dengan "Tentu saja" dan diakhiri dengan "perhatian yang Anda bayar".

Sed -n 12.18p file.txt

Hanya mengeluarkan baris 12-18 dari file.txt

Sed 12,18d file.txt

Mencetak seluruh file file.txt kecuali baris 12 hingga 18
Menyisipkan baris kosong setelah setiap baris di file.txt

sed -f script.sed file.txt

Menulis semua perintah ke script.sed dan menjalankannya.

Sed "5!s/ham/cheese/" file.txt

Mengganti ham dengan keju di file.txt kecuali baris ke-5

Sed "$d" file.txt

Menghapus baris terakhir

Sed -n "/\(3\)/p" file.txt

Hanya mencetak garis dengan tiga digit berurutan

Sed "/boom/s/aaa/bb/" file.txt

Jika "boom" ditemukan, ganti aaa dengan bb

Sed "17,/disk/d" file.txt

Menghapus semua baris dari baris 17 hingga "disk". Jika ada beberapa baris "disk", hapus hingga baris pertama.

Gema SATU DUA | sed "s/satu/unos/saya"

Mengganti satu dengan unos case-insensitive, jadi "unos TWO" akan dicetak

Sed "G;G" file.txt

Menyisipkan dua baris kosong setelah setiap baris di file.txt

Sed "s/.$//" file.txt

Sebuah cara untuk mengganti dos2unix :). Umumnya menghapus karakter terakhir di setiap baris.

Sed "s/^[ \t]*//" file.txt

Menghapus semua spasi/tab sebelum setiap baris di file.txt

Sed "s/[ \t]*$//" file.txt

Menghapus semua spasi/tab di akhir setiap baris di file.txt

Sed "s/^[ \t]*//;s/[ \t]*$//" file.txt

Menghapus semua spasi/tab di awal dan akhir setiap baris di file.txt

Sed "s/foo/bar/" file.txt

Mengganti foo dengan bar hanya pada kemunculan pertama dalam string.

Sed "s/foo/bar/4" file.txt

Menggantikan foo dengan bar hanya pada kemunculan keempat dalam string.

Sed "s/foo/bar/g" file.txt

Menggantikan foo dengan bar untuk semua kemunculan dalam string.

Sed "/baz/s/foo/bar/g" file.txt

Ganti foo dengan bar hanya jika string berisi baz.

Sed "/./,/^$/!d" file.txt

Kompres semua baris kosong berturut-turut menjadi satu. Tidak ada baris kosong di bagian atas.

Sed "/^$/N;/\n$/D" file.txt

Kompres semua baris kosong berturut-turut menjadi satu, tetapi biarkan baris kosong teratas.

Sed "/./,$!d" file.txt

Hapus semua baris kosong terkemuka

Sed -e:a -e "/^\n*$/($d;N;);/\n$/ba" file.txt

Hapus semua baris kosong yang tertinggal

Sed -e:a -e "/\\$/N; s/\\\n/ /; ta" file.txt

Jika sebuah baris diakhiri dengan garis miring terbalik, gabungkan dengan baris berikutnya (berguna untuk skrip shell)

Sed -n "/regex/,+5p" file.txt

Mencetak 5 baris setelah baris yang berisi regex

Sed "1~3d" file.txt

Hapus setiap baris ketiga, dimulai dengan yang pertama.

Sed -n "2~5p" file.txt

Cetak setiap baris kelima, mulai dari baris kedua.

Sed "s/ick/John/g" report.txt

Cara lain untuk menulis beberapa contoh di atas. Bisakah Anda menyarankan milik Anda?

sed -n "/RE/(p;q;)" file.txt

Mencetak string dengan kecocokan RE (ekspresi reguler) pertama

Sed "0,/RE/(//d;)" file.txt

Menghapus baris dengan kecocokan pertama

Sed "0,/RE/s//to_that/" file.txt

Hanya mengubah pertandingan pertama

Sed "s/^[^,]*,/9999,/" file.csv

Mengganti semua nilai di kolom pertama file CSV dengan 9999

S/^ *\(.*[^ ]\) *$/|\1|/; s/"*, */"|/g; :loop s/| *\([^",|][^,|]*\) *, */|\1|/g; s/| *, */||/g; t loop s/ *|/|/g ;s/|*/|/g;s/^|\(.*\)|$/\1/;

Skrip sed untuk mengonversi file CSV ke file dengan bilah vertikal sebagai pembatas (hanya berfungsi dengan beberapa jenis CSV, dengan tanda kutip dan koma yang disematkan).

Sed file ":a;s/\(^\|[^0-9.]\)\(\+\)\(\(3\)\)/\1\2,\3/g;ta" .txt

Mengubah format angka di file.txt dari 1234.56 menjadi 1.234.56

Sed -r "s/\<(reg|exp)+/\U&/g"

Mengonversi kata apa pun yang dimulai dengan reg atau exp menjadi huruf besar.

Sed "1.20s/Johnson/White/g" file.txt

Mengubah Johnson menjadi Putih hanya pada baris 1 - 20.

Sed "1,20 !s/Johnson/White/g" file.txt

Contoh sebelumnya dibalik (menggantikan semuanya kecuali baris 1-20)

Sed "/dari/,/sampai/ ( s/\<red\>/magenta/g; s/<blue\>/cyan/g; )" file.txt

Mengganti antara "dari" dan "sampai" saja. Jika ada beberapa area "dari" - "sampai", ganti di masing-masing area.

Sed "/ENDNOTES:/,$ ( s/Schaff/Herzog/g; s/Kraft/Ebbing/g; )" file.txt

Menggantikan hanya dari kata "ENDNOTES:" sampai EOF

Sed "/./(H;$!d;);x;/regex/!d" file.txt

Mencetak paragraf hanya jika berisi regex

Sed -e "/./(H;$!d;)" -e "x;/RE1/!d;/RE2/!d;/RE3/!d" file.txt

Mencetak paragraf hanya jika mengandung RE1, RE2 dan RE3. Urutan RE1, RE2 dan RE3 tidak masalah.

Sed "s/14"/empat belas inci/g" file.txt

Ini adalah bagaimana Anda dapat menggunakan tanda kutip ganda

Sed "s/\/some\/UNIX\/path/\/a\/new\/path/g" file.txt

Bekerja dengan Unix Paths

Sed "s///g" file.txt

Menghapus semua karakter yang dimulai dengan a dan diakhiri dengan g dari file file.txt

Masukkan "s/\(.*\)foo/\1bar/" file.txt

Menggantikan kecocokan terakhir foo dalam string dengan bar

Sed "1!G;h;$!d"

Mengganti Perintah tac

Sed "/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//"

Mengganti perintah rev

Sed 10q file.txt

Mengganti perintah kepala

Sed -e:a -e "$q;N;11,$D;ba" file.txt

Mengganti perintah ekor

Sed "$!N; /^\(.*\)\n\1$/!P; D" file.txt

Mengganti Perintah uniq

Sed "$!N; s/^\(.*\)\n\1$/\1/;t; D" file.txt

Perintah terbalik (setara dengan uniq -d)

Sed "$!N;$!D" file.txt

Setara dengan ekor -n 2

sed -n "$p" file.txt

... ekor -n 1 (atau ekor -1)

Sed "/regexp/!d" file.txt

setara grep

Sed -n "/regexp/(g;1!p;);h" file.txt

Mencetak baris yang muncul sebelum kecocokan pertama dari ekspresi reguler, tetapi tidak menyertakan kecocokan itu sendiri.

sed -n "/regexp/(n;p;)" file.txt

Mencetak baris setelah kecocokan pertama dari ekspresi reguler, tetapi tidak termasuk kecocokan itu sendiri.

sed "/pattern/d" file.txt

Menghapus pola pencocokan garis

Sed "/./!d" file.txt

Menghapus semua baris kosong dari file

Sed "/^$/N;/\n$/N;//D" file.txt

Kompres semua baris kosong berturut-turut menjadi dua baris kosong. Baris kosong tunggal tidak diubah.

Sed -n "/^$/(p;h;);/./(x;/./p;)" file.txt

Menghapus baris terakhir dari setiap paragraf
Mendapatkan tajuk email. Dengan kata lain - menghapus semuanya setelah baris kosong pertama.