Câu hỏi Làm thế nào để thay thế một ký tự bằng một dòng mới trong Vim?


Tôi đang cố gắng thay thế mỗi , trong tệp hiện tại bằng một dòng mới:

:%s/,/\n/g 

Nhưng nó chèn những gì trông giống như một ^@ thay vì một dòng mới thực sự. Tệp không ở chế độ DOS hoặc bất kỳ thứ gì.

Tôi nên làm gì?

Nếu bạn tò mò, như tôi, hãy kiểm tra câu hỏi Tại sao \ r một dòng mới cho Vim? cũng.


1591
2017-09-16 11:19


gốc


Stack Overflow là một trang web cho các câu hỏi lập trình và phát triển. Câu hỏi này dường như không có chủ đề vì nó không phải là về lập trình hay phát triển. Xem Tôi có thể hỏi những chủ đề nào ở đây trong Trung tâm trợ giúp. Có lẽ Siêu người dùng hoặc là Trao đổi ngăn xếp Unix & Linux sẽ là một nơi tốt hơn để hỏi. - jww
@ jww câu hỏi này là 10 tuổi ... dường như quá cũ để di chuyển. Có rất nhiều câu hỏi như thế này, ví dụ: stackoverflow.com/questions/10175812/… - Vinko Vrsalovic


Các câu trả lời:


Sử dụng \r thay vì \n.

Thay thế bởi \n chèn một ký tự null vào văn bản. Để có được một dòng mới, sử dụng \r. Khi nào đang tìm kiếm đối với dòng mới, bạn vẫn sẽ sử dụng \n, Tuy nhiên. Sự bất đối xứng này là do thực tế là \n và \r  làm những điều hơi khác nhau:

\n khớp với dòng kết thúc (dòng mới), trong khi \r phù hợp với một vận chuyển trở lại. Mặt khác, thay thế \n chèn một ký tự null trong khi \r chèn một dòng mới (chính xác hơn, nó được coi là đầu vào <CR>). Dưới đây là một ví dụ nhỏ, không tương tác để minh họa điều này, bằng cách sử dụng tính năng dòng lệnh Vim (nói cách khác, bạn có thể sao chép và dán phần sau vào một thiết bị đầu cuối để chạy nó). xxd hiển thị một tệp hexdump của tệp kết quả.

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.

Nói cách khác, \n đã chèn byte 0x00 vào văn bản; \r đã chèn byte 0x0a.


2076
2017-09-16 11:21



tại sao điều này hoạt động theo cách này? - Vinko Vrsalovic
/ r được coi là nhấn phím Enter / Return. Nó hoạt động trên tất cả các nền tảng. - Luka Marinko
vì bất kỳ lý do gì, thay thế tất cả '\ n bằng', \ n hoạt động khi thực hiện:% s / '\ n /', \ r / g - tipu
Xem thêm Tại sao \ r một dòng mới cho Vim?. - Andrew Marshall
Tôi muốn điều này làm việc cho vi cổ điển. Trên AIX v6.1, \r không hoạt động như thế này. Nhưng bạn có thể nhấn Ctrl-V  Enter thay vì nhập \r, Và nó hoạt động. - eksortso


Đây là mẹo:

Đầu tiên, đặt phiên vi (m) của bạn để cho phép khớp mẫu với các ký tự đặc biệt (ví dụ: dòng mới). Có lẽ đáng để đặt dòng này vào tệp .vimrc hoặc .exrc của bạn.

:set magic

Tiếp theo, hãy làm:

:s/,/,^M/g

Để có được ^M loại ký tự Điều khiển- -v va đanh Đi vào. Trong Windows, hãy làm Điều khiển- -q, Đi vào. Cách duy nhất tôi có thể nhớ những điều này là bằng cách ghi nhớ ít ý nghĩa của chúng:

A: Điều gì sẽ là nhân vật điều khiển tồi tệ nhất để sử dụng để đại diện cho một dòng mới?

B: Hoặc q (vì nó thường có nghĩa là "Thoát") hoặc v bởi vì nó sẽ rất dễ dàng để gõ Điều khiển- -c do nhầm lẫn và giết người biên tập.

A: Làm cho nó như vậy.


166
2017-09-25 23:40



Tôi đang sử dụng GVim trên Windows và tôi không cần :set magic (nó không có trong ~ / _vimrc của tôi) hoặc là ctrl-q. Chỉ đơn giản là một ctrl-v theo sau là nhập tạo ^M nhân vật cho tôi tốt. - Chris Phillips
C-v không đại diện cho một dòng mới; đó là lệnh "thoát nhân vật theo nghĩa đen". Tôi không biết những gì C-v là một nghi lễ cho một trong hai, nhưng có một lý do nó không tinh thần bản đồ để newline. - Jim Stewart
Ctrl-v là bản ghi nhớ cho "nguyên văn" - tức là thoát khỏi phím tiếp theo được nhấn vào mã khóa / ký tự "nguyên văn" của nó. Trong Windows nó dán: để giữ cho mọi thứ quen thuộc. Ctrl-Q là cho "(un) Trích dẫn" có thể. Khá ngu ngốc, dù sao - nhưng bạn có thể sử dụng nó trong các tệp nhị phân - ví dụ: để tìm kiếm Ctrl-A qua Ctrl-Z (Ascii 1-26 tôi đoán). - Tomasz Gandor
Bây giờ tôi phải loại bỏ thêm "," lệnh này được giới thiệu ... - Danny Wang
Ctrl-C không thực sự giết trình soạn thảo, mặc dù nó có thể hủy bạn trở lại chế độ Bình thường. Ctrl-V có nghĩa là nguyên văn, và Ctrl-Q có nghĩa là ai đó đã mắc lỗi khi tải $VIMRUNTIME/mswin.vim tập tin cấu hình. Bạn không cần mswin. Chỉ cần sử dụng vimrc của riêng bạn thay thế. - 00dani


Trong cú pháp s/foo/bar  \r và \n có ý nghĩa khác nhau, tùy thuộc vào ngữ cảnh.


Dành cho foo:
\ n = dòng mới
\ r = CR (vận chuyển trở về = Ctrl-M = ^ M)

Dành cho bar:
\ r = là dòng mới
\ n = null byte (0x00).


Tôi đã nhìn thấy câu hỏi về những thứ như vậy khá thường xuyên trong quá khứ, và đôi khi trong tương lai gần như không ai sẽ biết bất cứ điều gì về công cụ này cuối cùng ...

Theo yêu cầu 'phổ biến':

Đây là danh sách Ký tự điều khiển ASCII, chèn chúng vào vim thông qua CTRLvCTRL---Chìa khóa---.
Trong bash hoặc các shell unix / linux khác chỉ cần gõ CTRL---Chìa khóa---. Thử CTRLM trong bash, nó giống như đánh ĐI VÀO, như vỏ nhận ra những gì có nghĩa là, mặc dù các hệ thống Linux sử dụng Nguồn cấp dòng để phân định đường. Chỉ char điều khiển cho Nguồn cấp dữ liệu mới là CTRL-A, bị ràng buộc để 'nhảy đến đầu dòng' trong bash.

Để chèn chữ vào bash, CTRLv cũng sẽ hoạt động.

Hãy thử trong bash:

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

Sử dụng này Trình tự ANSI thoát, chèn hai ^[thông qua CTRLvESC.

Bạn cũng có thể thử CTRLvCTRLmĐI VÀO, sẽ cung cấp cho bạn điều này:

bash: $'\r': command not found

Nhớ cái gì đó \r từ phía trên? :>

Các Ký tự điều khiển ASCII danh sách khác với tiêu chuẩn bảng biểu tượng ascii, trong đó các ký tự điều khiển được chèn vào bảng điều khiển / pseudoterminal / vim thông qua CTRL key (haha), có thể tìm thấy ở đó. Trong khi đó, trong C và hầu hết các ngôn ngữ khác, bạn thường sử dụng các mã bát phân để đại diện cho các 'ký tự' này.

Nếu bạn thực sự muốn biết tất cả những điều này đến từ đâu: http://www.linusakesson.net/programming/tty/.
Đây là liên kết tốt nhất bạn sẽ đi qua về chủ đề này, nhưng hãy cẩn thận: Có những con rồng.


TL; DR

Thông thường foo = \nbar = \r.


65
2017-09-23 14:00



Vì vậy, tôi tò mò làm thế nào bạn sẽ thay thế một nhân vật với một vận chuyển trở lại - codeshot
@codeshot :s/x/^M/g nên làm. Chèn ^M thông qua ctrl-v theo dõi bởi ctrl-m. - sjas
Cảm ơn sjas, Bạn biết câu hỏi này là một trong những câu hỏi kỳ lạ nhất mọi thời đại. 1008 phiếu cho câu trả lời mà về cơ bản không nói gì hơn "vim làm những gì bạn tìm thấy. Đó là bởi vì vim làm những gì bạn tìm thấy. Không bao giờ quên rằng vim làm những gì bạn tìm thấy." Tôi hy vọng sẽ tìm thấy một danh sách ngắn các mã cho các nhân vật thú vị trong mô hình, sự thay thế và lý do cho sự kỳ quặc để dễ nhớ và dự đoán sự kỳ quặc tương tự khác. Điều đó sẽ có được phiếu bầu của tôi. - codeshot
@codeshot danh sách các ký tự điều khiển ascii có thể giúp bạn. Xem cs.tut.fi/~jkorpela/chars/c0.html để tham khảo thêm. Tôi sẽ cập nhật câu trả lời của tôi để bao gồm hai liên kết. - sjas
@codeshot Tôi đã cập nhật bài đăng một lần nữa bằng những thứ bạn có thể thấy thú vị. Kể từ khi HARD của nó để tìm thông tin về điều này thông qua google trong một writeup mạch lạc, tôi đoán một blogpost trên những điều này là quá hạn ... - sjas


Bạn cần sử dụng

:%s/,/^M/g

Để có được ^M nhân vật, nhấn Ctrl  v theo dõi bởi Đi vào


45
2017-09-16 11:30



Tôi phải làm <C-v> <C-m> để lấy ký tự ^ M. - Jezen Thomas


\r có thể làm công việc ở đây cho bạn.


27
2017-09-16 11:21





Với Vim sử dụng Windows Ctrl+Q thay cho Ctrl+V


20
2017-09-16 11:45





Từ nhật thực, ^M ký tự có thể được nhúng vào một dòng và bạn muốn chuyển đổi chúng thành dòng mới.

:s/\r/\r/g

8
2017-09-06 17:53





Nhưng nếu người ta phải thay thế thì điều sau đây hoạt động

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

ở trên mỗi dòng kế tiếp được thay thế bằng dòng tiếp theo và sau đó | - và một lần nữa dòng tiếp theo. Điều này được sử dụng trong các bảng wiki. nếu văn bản như sau:

line1
line2
line3

được thay đổi thành

line1
|-
line2
|-
line3

5
2018-02-07 08:09





Đây là câu trả lời tốt nhất cho cách tôi nghĩ nhưng nó sẽ đẹp hơn trong một bảng: https://stackoverflow.com/a/12389839/962394.

Vì vậy, viết lại:

Bạn cần sử dụng \r để sử dụng nguồn cấp dữ liệu dòng (ascii 0x0a, unix newline) trong một thay thế regex nhưng đó là đặc biệt để thay thế - bạn thường nên tiếp tục mong đợi để sử dụng \n cho nguồn cấp dữ liệu dòng và \r cho vận chuyển trở lại.

Điều này là do vim được sử dụng \n trong một sự thay thế có nghĩa là nhân vật NIL (ascii 0x00). Bạn có thể đã mong đợi NIL đã được \0 thay vào đó, giải phóng \n để sử dụng thông thường cho nguồn cấp dữ liệu dòng nhưng \0 đã có ý nghĩa trong các thay thế regex nên nó đã được chuyển sang \n. Do đó, sau đó đi xa hơn để chuyển đổi dòng mới từ \n đến \r (mà trong một mẫu regex là ký tự trả về vận chuyển, ascii 0x0d).

nhân vật | mã ascii | C đại diện | trận đấu regex | regex thay thế
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
nil | 0x00 | \ 0 | \ 0 | \ n
nguồn cấp dữ liệu dòng (unix newline) | 0x0a | \ n | \ n | \ r
vận chuyển trở lại | 0x0d | \ r | \ r | <unknown>

NB: ^M (Ctrl-V Ctrl-M trên Linux) chèn một dòng mới khi được sử dụng trong một thay thế regex hơn là một vận chuyển trở lại như những người khác đã khuyên (tôi chỉ cần thử nó).

Cũng lưu ý rằng vim sẽ dịch ký tự cấp dữ liệu dòng khi nó lưu vào tệp dựa trên cài đặt định dạng tệp của nó và điều đó có thể gây nhầm lẫn cho các vấn đề.


5
2018-04-08 12:15





Nếu bạn cần phải làm cho toàn bộ một tập tin, nó cũng đã được đề nghị với tôi rằng bạn có thể thử từ dòng lệnh

sed 's/\\n/\n/g' file > newfile

4
2018-02-09 23:01



Lưu ý rằng điều này đòi hỏi GNU sed. Thử printf 'foo\\nbar\n' | sed 's/\\n/\n/g' để xem liệu nó có hoạt động trên hệ thống của bạn hay không. (Tín dụng cho những người tốt của #bash trên freenode cho đề xuất này.) - Evan Donovan