Bagaimana cara mengganti beberapa baris dengan satu kata dalam file (inplace replace)?

9

Konten filenamefile saya adalah sebagai berikut (misalnya):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

Saya ingin mengganti blok garis antara STARTdan ENDhanya dengan satu kata, misalnya dengan SINGLEWORD. Seperti di bawah ini:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Saya dapat menemukan blok baris saya dengan menggunakan perintah ini:

grep -Pzo "START(.|\n)*END" filename

Dan hasil menjalankan perintah di atas akan seperti ini:

START
First line
second line
third line
END

Lalu saya menggunakan perintah ini untuk menggabungkan semua baris menjadi satu baris:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

Maka saya akan mendapatkan hasil ini:

START First line second line third line END

Dan dengan perintah terakhir saya, LAST_RESULTS | sed 's/.*/SINGLEWORD/'saya mengubahnya "SINGLEWORD"dan saya mendapatkan hasil ini.

SINGLEWORD

Sekarang yang saya inginkan adalah: Bagaimana saya bisa menggunakan perintah ini (atau perintah saran Anda) dan mengganti (di tempat) blok baris saya menjadi kata "SINGLEWORD"? Dan hasil akhirnya akan seperti file ini:

My block of line starts from here 
SINGLEWORD
and end to here for example.
αғsнιη
sumber

Jawaban:

14

Ini dapat dilakukan dengan sangat mudah di perl:

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

Penjelasan

-0 set pemisah baris ke nol

-pterapkan skrip yang diberikan oleh -euntuk setiap baris dan cetak baris itu

Pengubah regexp:

  • /sPerlakukan string sebagai satu baris. Artinya, ubah .untuk mencocokkan karakter apa pun, bahkan baris baru, yang biasanya tidak cocok.

Mengapa ?:

  • Secara default, subpattern yang dikuantifikasi adalah "serakah", yaitu, ia akan cocok sebanyak mungkin (diberikan lokasi awal tertentu) sambil tetap membiarkan sisa pola untuk mencocokkan. Jika Anda ingin mencocokkan dengan jumlah minimum yang dimungkinkan, ikuti penghitung dengan a ?.
Sylvain Pineau
sumber
@KasiyA: Penggunaan sedharus dimungkinkan tetapi mungkin lebih sulit untuk dibaca (Lihat pertanyaan ini )
Sylvain Pineau
Satu lagi karena saya START dan END pola memiliki karakter khusus ( /, *, ?) di dalamnya dan ini hanya contoh. dan bisakah Anda menjelaskan perintah Anda.
αғsнιη
@KasiyA Anda dapat melarikan diri karakter tersebut dengan \ (persis seperti dengan sed): \/, \*,\?
Sylvain Pineau
@ KasiyA saya mencoba perl -i -p0e 's/\/\*.*?\*\//SINGLEWORD/sm'. Seharusnya berhasil
Sylvain Pineau
@ KasiyA Saya pikir saya sudah selesai dengan penjelasan sekarang;)
Sylvain Pineau
14

Saya bertanya-tanya apakah ini mungkin tanpa perl, pythondan lain-lain. Dan saya menemukan solusi ini menggunakan sed:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

Penjelasan:

  1. : a buat label 'a'
  2. N menambahkan baris berikutnya ke ruang pola
  3. $! jika bukan baris terakhir , ba cabang (buka) beri label 'a'
  4. s pengganti , /START.*END/oleh SINGLEWORD, / g pertandingan global (sebanyak yang bisa)

Itu ditemukan di sini .

@KasiyA, terima kasih saya telah belajar banyak hal menarik!

c0rp
sumber