Saya melihat pertanyaan ini dan bertanya-tanya bagaimana saya bisa menerapkan jawaban saya yang menggunakan
sed
menggunakan POSIX
ex
murni
.
Kuncinya adalah bahwa sementara sed
saya bisa membandingkan ruang pegang dengan ruang pola untuk melihat apakah mereka benar-benar setara (dengan
G;/^\(.*\)\n\1$/{do something}
), saya tahu tidak ada cara untuk melakukan tes seperti itu ex
.
Saya tahu bahwa di Vim saya bisa melakukan Y
ank pada baris pertama dan kemudian mengetik
:2,$g/<C-r>0/d
untuk hampir melakukan apa yang saya tentukan — tetapi jika baris pertama berisi apa pun kecuali teks alfanumerik yang sangat mudah, ini memang untung-untungan, karena garis tersebut dibuang sebagai
regex , bukan hanya string untuk perbandingan. (Dan jika baris pertama berisi garis miring, sisa baris akan ditafsirkan sebagai perintah!)
Jadi jika saya ingin menghapus semua baris myfile
yang identik dengan baris pertama — tetapi tidak menghapus baris pertama — bagaimana saya bisa menggunakan itu ex
? Untuk itu, bagaimana saya bisa menggunakannya vi
?
Apakah ada cara POSIX untuk menghapus sebuah baris jika benar-benar cocok dengan baris lain?
Mungkin sesuatu seperti sintaks imajiner ini:
:2,$g/**lines equal to "0**/d
sed
sebagai filter dari dalam ex
, dan menjalankan seluruh sed
jawaban saya di seluruh buffer ... yang akan bekerja, tentu saja (dan sebenarnya portabel tidak seperti sed -i
).
<C-r>0
sangat baik. Saya tidak yakin Anda bisa melakukan yang lebih baik dengan hanya perintah Ex karena Anda harus melindungi karakter khusus. Tanpa kendala yang sesuai dengan POSIX, saya pikir Anda akan menggunakan saklar yang sangat nomagik \V
dan kemudian Anda akan melindungi backslash (karena tetap mempertahankan makna khususnya \V
) dengan escape()
fungsi yang argumen ke-2nya adalah string yang berisi semua karakter yang ingin Anda hindari / lindungi. .
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
Atau Anda bisa menggunakan karakter lain untuk pembatas pola seperti titik koma. Dalam hal ini, Anda tidak perlu melindungi garis miring ke depan dalam polanya. Ini akan memberikan sesuatu seperti::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
sangat baik. Dengan Vim, Anda sering mendelegasikan tugas khusus tertentu ke program lain, dan sed
mungkin merupakan contoh yang baik untuk itu. Omong-omong, Anda tidak harus menjalankan sed
seluruh buffer Anda. Jika Anda ingin menjalankannya hanya pada sebagian buffer, Anda bisa memberikan rentang. Misalnya, jika Anda ingin menyaring hanya garis antara 50 dan 100, Anda bisa mengetik: :50,100!<your sed command>
.
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'