Pertama-tama, dengan ini menjadi posting pertama saya di sini, saya hanya ingin mengatakan bahwa saya telah menemukan VIM sebagai alat yang hebat dan forum di sini sangat membantu dalam menemukan jawaban atas pertanyaan, dengan banyak orang yang membantu menyediakan bantuan yang tak ternilai. Saya masih sangat baru untuk VIM, jadi hampir semua yang saya pelajari tentang itu berasal dari sini.
Pertanyaan saya adalah: Saya tahu cara membalikkan SEMUA baris dalam file (: g / ^ / m0 antara lain), tetapi apakah ada cara untuk membalikkan setiap 4 baris dalam file, sehingga
line1
line2
line3
line4
line5
line6
line7
line8
...
menjadi
line4
line3
line2
line1
line8
line7
line6
line5
...
Anda dapat mengasumsikan bahwa akan selalu ada kelipatan tepat dari 4 baris dalam file tersebut.
Jawaban:
Perintah yang
:Reverse
dijelaskan di Vim Wiki dapat digunakan untuk ini (Anda dapat memasukkannya ke dalam.vimrc
untuk membuatnya permanen):Kemudian Anda bisa merekam makro untuk menjalankan perintah di setiap empat baris:
Penjelasan:
qm
: 'q' dalam mode normal dimulai (dan berhenti) merekam makro dalam register yang diberikan (register 'm', dalam hal ini, tetapi bisa berupa huruf lain)V
: masuk ke mode visual dan pilih garis saat ini3j
: perluas seleksi visual ke 3 baris berikutnya:Reverse<cr>
: jalankan perintah Reverse pada baris yang dipilih (di<cr>
sini adalah enterkunci)4j
: pergi ke baris tidak berubah berikutnyaq
: berhenti merekam makro1000@m
: jalankan makro yang tercatat pada register 'm' 1000 kali (Anda dapat menambah nomor ini jika file Anda lebih besar dari 4000 baris)Edit:
Seperti yang disebutkan dalam komentar, Anda bisa menggunakan makro rekursif alih-alih menggunakan hitungan:
qM
: jika register yang ditentukan untukq
huruf besar, makro ditambahkan ke register (yang juga berguna ketika Anda menyadari ketika Anda melewatkan langkah terakhir pada makro kompleks)@m
: jalankan makro saat mendaftarm
q
: berhenti menambahkan makroMeskipun dibuat sebagai makro, Anda bisa membuat perintah untuk ini jika itu adalah tugas umum pada alur kerja Anda:
function! Reverse4()
/endfunction
: mendefinisikan fungsi barulet reg_m = @m
: menyimpan isi register saat inim
let @m = "<c-r><c-r>m"
: masukkan makro dalam registerm
- perhatikan bahwa itu<c-r>
adalah notasi vim untuk Ctrl+ rdan Anda harus mengetik ini, bukan menyalin / menempel, sehingga baris Anda akan miriplet @m = 'V3j:Reverse^M4j@m'
dan itu akan berisi karakter khusus (^ M)normal! @m
: perintah normal menjalankan argumennya seperti yang telah diketik dalam mode normal, sehingga akan menjalankan makro rekursiflet @m = reg_m
: mengembalikan konten registerm
, jadi Anda tidak harus ingat bahwa register ini digunakan pada fungsi ini dan hindari menggunakannyacommand! Reverse4 call Reverse4()
: buat perintah baru untuk fungsi iniBergantung pada kebutuhan Anda, Anda dapat meningkatkannya, misalnya: meneruskan argumen ke perintah dan fungsi sehingga akan berfungsi untuk sejumlah baris alih-alih diperbaiki dalam kelompok 4 baris.
sumber
1000@q
hack, Anda juga dapat menggunakan makro rekursif:qmqqm ... @mq@m
.command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
di suatu tempat di vimrc Anda.Seperti semua tindakan berulang , jika Anda dapat melakukan sesuatu sekali dengan operasi edit dasar, maka Anda dapat dengan mudah melakukannya berkali-kali dengan merekam makro.
(Dalam hal ini saya akan menggunakan makro rekursif, tetapi Anda bisa merekam yang tidak rekursif dan memutarnya berulang kali dengan memalu
@@
atau menggunakan hitungan.)Rusak
gg
: Pindah ke awal file.qqq
: Hapus registerq
. Kita akan melihat mengapa ini perlu di langkah 5.qq
: Mulai merekam makro untuk mendaftar qddjjpkddkkPjddpjj
: Serangkaian operasi yang menata ulang empat baris pertama hanya dengan menghapus dan menempelkannya secara manual. (Ini mungkin terlihat rumit pada pandangan pertama, tapi jangan tertipu ini adalah hal yang sangat mendasar bahwa Anda akan belajar dalam 5 menit atau lebih dari.vimtutor
:j
,k
,dd
,p
,P
)@q
: Panggil makro! Pada titik ini, registerq
tidak mengandung apa-apa (karena kami membersihkannya pada langkah 2), jadi tidak ada yang terjadi.q
: Berhenti merekam makro.@q
: Putar ulang makro rekursif sebanyak yang diperlukan.NB Di atas tidak akan menghasilkan hasil yang diinginkan jika file berisi sejumlah baris yang tidak bisa dibagi empat. Untuk menghentikan makro lebih awal jika tidak ada empat baris yang tersisa, kita perlu melakukan perintah normal-mode Vim yang akan gagal, sebelum kita mulai menerapkan suntingan di langkah 4. Kita bisa melakukan ini dengan mencoba bergerak turun garis tiga kali (dan kemudian kembali) sebelum kita mulai memindahkan garis:
jjj3k
Jadi:
sumber
q
, itu harus kosong, jika tidak maka akan mengacaukan edisi Anda.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
where I can just use the one-line custom command each time I need to do this
- perhatikan bahwa Anda tidak harus membuat kembali makro setiap kali Anda perlu menggunakannya, karena dimungkinkan untuk menyimpannya sebagai fungsi / perintah pada vimrc Anda.Anda juga dapat melakukan ini dengan
Ex
perintah menggunakansed
sebagai filter eksternal:Versi ini akan mengabaikan (menghapus) setiap baris tambahan di luar kelipatan 4. Untuk mempertahankan set terakhir kurang dari 4 baris (terbalik), gunakan:
Di
%
sini berarti "Setiap baris dalam buffer."The
!
berarti perintah "Jalankan perintah berikut dengan garis ditetapkan sebagai masukan, dan menggantikan garis-garis yang ditentukan dengan output dari perintah." (Ini disebut filter; sangat berguna untuk hal-hal seperti menyortir, misalnya,:%!sort
akan mengurutkan semua baris dalam file Anda;:2,8!sort
akan mengurutkan baris 2-8, dll.)sed
adalah alat editor aliran dan ditemukan di semua sistem mirip Unix. Konsep kunci yangsed
digunakan di sini adalah "pola ruang" (yang secara default hanya berisi setiap baris input pada gilirannya), dan "ruang pegang" (di mana Anda dapat menempel teks tambahan saat menggunakansed
untuk menyimpannya saat memproses lainnya jalur input).-n
adalah opsi untuksed
perintah untuk menekan tindakan standar mencetak ruang pola (karena dalam hal ini kami hanya ingin mencetak ketika kami secara eksplisit mengatakannya.)$p
dalamsed
perintah berarti "Jika Anda berada di baris terakhir darised
input, cetak (ruang pola)."h
berarti "menempelkan isi saat ini dari 'ruang pola' di 'ruang tahan', menimpa apa pun yang ada di sana."n
berarti "ganti isi dari 'ruang pola' dengan baris berikutnya dari input."G
berarti "menambahkan ke 'ruang pola': baris baru diikuti dengan isi 'ruang tahan'."Secara keseluruhan,
sed
perintah menyimpan empat baris output, membalikkannya saat menyimpannya, dan kemudian mencetaknya. The$p
perintah ditambahkan dalam versi kedua memastikan bahwa jika baris terakhir dari file telah dicapai selain di kelipatan dari 4 baris, baris masih dicetak.Untuk alternatif, pendekatan interaktif masih tanpa menggunakan fitur spesifik Vim dan juga tanpa menggunakan filter eksternal:
untuk menuju ke baris keempat.
untuk membalikkan empat baris sebelumnya (1-4) dan biarkan kursor Anda berada di jalur 8.
.m -4
memindahkan garis saat ini tepat setelah garis empat garis kembali (meninggalkan kursor pada garis yang dipindahkan).+3m .
memindahkan garis yang 3 baris setelah garis saat ini, hanya setelah garis saat ini, meninggalkan kursor pada garis yang dipindahkan.+2m .
tentu saja kerjanya sama.+5
menempatkan kursor lima baris ke bawah dari tempatnya.Ulangi sesuai yang diinginkan.
Di Vim Anda dapat mengulangi seluruh perintah ini dengan
@:
, lalu ulangi lagi dengan@@
. Dalam POSIXvi
atauex
Anda perlu memasukkan:.m -4 | +3m . | +2m . | +5
sebagai baris teks, hapus itu ke buffer bernama (register), dan kemudian jalankan buffer bernama itu (register).Jadi dalam
ex
mode, membalikkan garis secara interaktif hanya menggunakan fitur yang ditentukan POSIX, dan mulai dengan 17 baris teks:Bacaan lebih lanjut:
ex
vi
sumber
4G:.m -4 | +3m . | +2m . | +5<Enter>@:
kemudian@@
diulangi hingga file Anda sepenuhnya diproses. Saya sarankan menginstal MobaXterm. :)Bahasa Inggris Biasa: Untuk setiap baris, gerakkan garis saat ini ke atas
lnum % 4
, kecualilnum % 4 == 0
, dalam hal mana memindahkan garis saat ini ke atas4
.Juga, untuk membalikkan setiap
n
baris, ganti4
's di perintah di atas dengann
.sumber