Bagaimana cara mengganti karakter dengan baris baru di Vim

1967

Saya mencoba mengganti masing-masing ,dalam file saat ini dengan baris baru:

:%s/,/\n/g 

Tapi itu menyisipkan apa yang tampak seperti ^@bukan baris baru yang sebenarnya. File tidak dalam mode DOS atau apa pun.

Apa yang harus saya lakukan?

Jika Anda penasaran, seperti saya, periksa pertanyaan Mengapa baris baru untuk Vim? demikian juga.

Vinko Vrsalovic
sumber
2
Stack Overflow adalah situs untuk pertanyaan pemrograman dan pengembangan. Pertanyaan ini tampaknya di luar topik karena ini bukan tentang pemrograman atau pengembangan. Lihat Topik apa yang bisa saya tanyakan di sini di Pusat Bantuan. Mungkin Super User atau Unix & Linux Stack Exchange akan menjadi tempat yang lebih baik untuk bertanya.
jww
5
@jww pertanyaan ini berumur 10 tahun ... sepertinya terlalu tua untuk dimigrasi. Ada banyak pertanyaan seperti ini, misalnya: stackoverflow.com/questions/10175812/…
Vinko Vrsalovic
14
@jww vim adalah alat yang biasa digunakan untuk programmer, dan pertanyaan tentang alat yang biasa digunakan untuk programmer ada di topik di Stack Overflow . Meskipun jelas ini lebih cocok untuk Vi dan Vim .
user202729

Jawaban:

2565

Gunakan \rsebagai ganti \n.

Mengganti dengan \nmemasukkan karakter nol ke dalam teks. Untuk mendapatkan baris baru, gunakan \r. Saat mencari baris baru, Anda masih akan menggunakan \n. Asimetri ini disebabkan oleh fakta bahwa \ndan \r melakukan hal-hal yang sedikit berbeda :

\ncocok dengan akhir baris (baris baru), sedangkan \rcocok dengan carriage return. Di sisi lain, dalam substitusi \nmenyisipkan karakter nol sedangkan \rmenyisipkan baris baru (lebih tepatnya, itu diperlakukan sebagai input <CR>). Berikut adalah contoh kecil, non-interaktif untuk menggambarkan hal ini, menggunakan fitur baris perintah Vim (dengan kata lain, Anda dapat menyalin dan menempel berikut ini ke terminal untuk menjalankannya). xxdmemperlihatkan hexdump dari file yang dihasilkan.

echo bar > test
(echo 'Before:'; xxd test) > output.txt
vim test '+s/b/\n/' '+s/a/\r/' +wq
(echo 'After:'; xxd test) >> output.txt
more output.txt
Before:
0000000: 6261 720a                                bar.
After:
0000000: 000a 720a                                ..r.

Dengan kata lain, \ntelah memasukkan byte 0x00 ke dalam teks; \rtelah memasukkan byte 0x0a.

Konrad Rudolph
sumber
127
/ r diperlakukan sebagai menekan tombol Enter / Return. Ini bekerja di semua platform.
Luka Marinko
73
Lihat juga Mengapa baris baru untuk Vim? .
Andrew Marshall
14
Saya berharap ini berhasil untuk vi klasik. Pada AIX v6.1, \rtidak berfungsi seperti ini. Tapi Anda bisa menekan Ctrl-V Enterdi tempat mengetik \r, dan itu berhasil.
eksortso
3
Saya terlambat ke pesta. Jika \rmemasukkan <CR>dan \nmemasukkan nol, bagaimana saya akan mengganti sesuatu dengan carriage return?
Tn. Llama
2
@ SunnyRaj Anda yakin tentang sejarah CR dan LF? Saya mendapat kesan bahwa awalnya LF memindahkan kertas satu baris ke depan tetapi tidak memindahkan printhead, dan CR memindahkan printhead tetapi tidak memindahkan kertas. Akibatnya, jika OS Anda tidak mengonversi input sebelum dicetak, Anda tidak bisa hanya menggunakan LF atau CR untuk mendapatkan output yang benar. MS DOS menggunakan data printer mentah sebagai format file teks, Mac OS menggunakan CR dan dikonversi dari itu ke format mentah printer dan UNIX menggunakan LF dan dikonversi dari itu ke format mentah printer.
Mikko Rantalainen
210

Inilah triknya:

Pertama, atur sesi Vi (m) Anda untuk memungkinkan pencocokan pola dengan karakter khusus (yaitu: baris baru). Mungkin layak menempatkan baris ini di file .vimrc atau .exrc Anda:

:set magic

Selanjutnya, lakukan:

:s/,/,^M/g

Untuk mendapatkan ^Mkarakter, ketik Ctrl+ Vdan tekan Enter. Pada Windows, lakukan Ctrl+ Q, Enter. Satu-satunya cara saya dapat mengingat ini adalah dengan mengingat betapa sedikitnya pengertian mereka:

A: Apa yang akan menjadi karakter kontrol terburuk yang digunakan untuk mewakili baris baru?

B: Entah q(karena biasanya berarti "Berhenti") atau vkarena itu akan mudah untuk mengetik Ctrl+ Csecara tidak sengaja dan membunuh editor.

A: Jadikan begitu.

Logan
sumber
9
Saya menggunakan GVim di Windows, dan saya tidak membutuhkan :set magic(itu tidak ada di ~ / _vimrc saya) atau ctrl-q. Hanya ctrl-vdiikuti oleh enter sederhana menciptakan ^Mkarakter bagi saya baik-baik saja.
Chris Phillips
5
Cv tidak mewakili baris baru; itu adalah perintah "escape next literal character". Saya tidak tahu apa itu Cv mnemonik untuk keduanya, tetapi ada alasan mengapa tidak secara mental memetakan ke baris baru.
Jim Stewart
27
Ctrl-v adalah mnemonik untuk "kata demi kata" - yaitu melarikan diri dari tombol berikutnya yang ditekan ke kode / "kata kunci". Di Windows, rekatkan: untuk membuat hal-hal tetap familier. Ctrl-Q untuk "(un) Quote" mungkin. Cukup bodoh, bagaimanapun - tetapi Anda dapat menggunakannya dalam file biner - misalnya untuk mencari Ctrl-A melalui Ctrl-Z (Ascii 1-26 kurasa).
Tomasz Gandor
1
Ctrl-Ctidak benar-benar membunuh editor, meskipun itu dapat membatalkan Anda kembali ke mode Normal. Ctrl-Vberarti kata demi kata, dan Ctrl-Qberarti seseorang membuat kesalahan saat memuat $VIMRUNTIME/mswin.vimfile konfigurasi. Anda tidak perlu mswin. Cukup gunakan vimrc Anda sendiri sebagai gantinya.
00dani
wow ---- ini luar biasa. Dulu saya lakukan sed -n l sampai sekarang. Senang mengetahui bahwa hal yang sama dapat dicapai dengan Ctrl-vvim.
arpit
98

Dalam sintaksis s/foo/bar, \rdan \nmemiliki arti yang berbeda, tergantung konteksnya.


Pendek:

Untuk foo:

\ n = baris baru (LF di Linux / Mac, CR + LF di Windows)
\ r = carriage return (CR)

Untuk bar:

\ r = adalah baris baru
\ n = byte nol.

Lebih lama (dengan nomor ASCII):

NUL= 0x00 = 0 = Ctrl+ @
LF= 0x0A = 10 = Ctrl+ J
CR= 0x0D = 13 = Ctrl+M

Berikut adalah daftar karakter kontrol ASCII . Masukkan mereka di Vim via Ctrl+ V, Ctrl+ ---key---.

Di Bash atau shell Unix / Linux lainnya, cukup ketik Ctrl+ ---key---.

Coba Ctrl+ Mdi Bash. Itu sama dengan memukul Enter, ketika shell menyadari apa yang dimaksud, meskipun sistem Linux menggunakan umpan garis untuk pembatasan garis.

Untuk memasukkan literal di bash, menambahkannya dengan Ctrl+ Vjuga akan berfungsi.

Coba di Bash:

echo ^[[33;1mcolored.^[[0mnot colored.

Ini menggunakan urutan pelarian ANSI . Insert dua ^['s via Ctrl+ V, Esc.

Anda juga dapat mencoba Ctrl+ V, Ctrl+ M, Enteryang akan memberikan Anda ini:

bash: $'\r': command not found

Ingat \rdari atas? :>

Ini karakter kontrol ASCII daftar berbeda dari lengkap tabel simbol ASCII , dalam bahwa karakter kontrol, yang dimasukkan ke dalam konsol / pseudoterminal / Vim melalui Ctrlkunci (haha), dapat ditemukan di sana.

Sedangkan di C dan sebagian besar bahasa lain, Anda biasanya menggunakan kode oktal untuk mewakili 'karakter' ini.

Jika Anda benar-benar ingin tahu dari mana semua ini berasal: TTY didemistifikasi . Ini adalah tautan terbaik yang akan Anda temui tentang topik ini, tetapi berhati-hatilah: Ada naga.


TL; DR

Biasanya foo= \n, dan bar= \r.

sja
sumber
1
Jadi saya tertarik bagaimana Anda akan mengganti karakter dengan carriage return
codeshot
2
@codeshot :s/x/^M/gharus melakukannya. Masukkan ^Mvia ctrl-vdiikuti oleh ctrl-m.
sjas
3
Terima kasih sja, Anda tahu pertanyaan ini adalah salah satu yang paling aneh sepanjang masa. 1008 suara untuk jawaban yang pada dasarnya mengatakan tidak lebih dari "vim melakukan apa yang Anda temukan. Itu karena vim melakukan apa yang Anda temukan. Jangan pernah lupa bahwa vim melakukan apa yang Anda temukan." Saya berharap menemukan daftar kode untuk karakter yang menarik dalam pola, penggantian dan alasan keanehan sehingga mudah diingat dan memprediksi keanehan serupa lainnya. Itu akan mendapatkan suara saya.
codeshot
@codeshot daftar karakter kontrol ascii mungkin membantu Anda. Lihat cs.tut.fi/~jkorpela/chars/c0.html untuk referensi lebih lanjut. Saya akan memperbarui jawaban saya untuk memasukkan dua tautan.
sjas
55

Anda perlu menggunakan:

:%s/,/^M/g

Untuk mendapatkan ^Mkarakter, tekan Ctrl+ vdiikuti oleh Enter.

dogbane
sumber
4
Saya harus melakukan <Cv> <Cm> untuk mendapatkan karakter ^ M.
Jezen Thomas
39

\r dapat melakukan pekerjaan di sini untuk Anda.

Lasar
sumber
24

Dengan Vim di Windows, gunakan Ctrl+ Qsebagai pengganti Ctrl+ V.

hibah
sumber
16

Ini adalah jawaban terbaik untuk cara saya berpikir, tetapi akan lebih baik di tabel:

Mengapa newline untuk Vim?

Jadi, menulis ulang:

Anda perlu menggunakan \runtuk menggunakan umpan baris (ASCII 0x0A, baris baru Unix) dalam penggantian regex, tetapi itu khusus untuk penggantian - Anda biasanya harus terus berharap untuk menggunakan \numpan baris dan \runtuk pengembalian carriage.

Ini karena Vim digunakan \nsebagai pengganti karakter NIL (ASCII 0x00). Anda mungkin mengharapkan NIL \0sebagai gantinya, membebaskan \nuntuk penggunaan yang biasa untuk umpan baris, tetapi \0sudah memiliki arti dalam penggantian regex, sehingga dialihkan ke \n. Oleh karena itu kemudian melangkah lebih jauh dengan menggeser baris baru dari \nke \r(yang dalam pola regex adalah karakter carriage return, ASCII 0x0D).

Karakter | Kode ASCII | Representasi C | Pertandingan Regex | Penggantian Regex
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
nihil | 0x00 | \ 0 | \ 0 | \ n
umpan baris (Batalkan baris baru) | 0x0a | \ n | \ n | \ r
carriage return | 0x0d | \ r | \ r | <unknown>

NB: ^M( Ctrl+ V Ctrl+ Mdi Linux) menyisipkan baris baru saat digunakan dalam penggantian regex daripada carriage return seperti yang disarankan orang lain (saya baru mencobanya).

Juga perhatikan bahwa Vim akan menerjemahkan karakter umpan baris ketika menyimpan ke file berdasarkan pengaturan format file dan yang mungkin membingungkan masalah.

codeshot
sumber
11

Dari Eclipse , ^Mkarakter dapat disematkan dalam satu baris, dan Anda ingin mengubahnya menjadi baris baru.

:s/\r/\r/g
rickfoosusa
sumber
8

Tetapi jika seseorang harus mengganti, maka hal berikut berfungsi:

:%s/\n/\r\|\-\r/g

Di atas, setiap baris berikutnya diganti dengan baris berikutnya, dan kemudian |-lagi baris baru. Ini digunakan dalam tabel wiki.

Jika teksnya sebagai berikut:

line1
line2
line3

Itu diubah menjadi

line1
|-
line2
|-
line3
Kiran K Telukunta
sumber
7

Jika Anda perlu melakukannya untuk seluruh file, disarankan juga kepada saya bahwa Anda dapat mencoba dari baris perintah:

sed 's/\\n/\n/g' file > newfile
Evan Donovan
sumber
1
Perhatikan bahwa ini membutuhkan GNU sed. Cobalah printf 'foo\\nbar\n' | sed 's/\\n/\n/g'untuk melihat apakah itu akan berfungsi pada sistem Anda. (Penghargaan untuk orang-orang baik #bash di freenode untuk saran ini.)
Evan Donovan
Ya, tetapi pertanyaannya adalah tentang Vim. Ada pertanyaan Stack Overflow Bagaimana saya bisa mengganti baris baru (\ n) menggunakan sed? .
Peter Mortensen
5

Inilah jawaban yang bekerja untuk saya. Dari pria ini:

---- mengutip Gunakan editor vi untuk memasukkan karakter baris baru sebagai ganti


Hal lain yang harus saya lakukan dan tidak dapat mengingat dan kemudian harus melihat ke atas.

Di vi, untuk menyisipkan karakter baris baru dalam pencarian dan ganti, lakukan hal berikut:

:%s/look_for/replace_with^M/g

Perintah di atas akan mengganti semua instance "look_for" dengan "replace_with \ n" (dengan \ n yang berarti baris baru).

Untuk mendapatkan "^ M", masukkan kombinasi tombol Ctrl+ V, dan kemudian setelah itu (lepaskan semua tombol) tekan Entertombol.


Peter Mortensen
sumber