Vim - jak zamienić jedną nową linię \ n na dwie \ n's

34

W edytorze vim chcę zastąpić znak nowej linii (\ n) dwoma znakami nowej linii (\ n \ n), używając trybu polecenia vim.

Zawartość pliku wejściowego:

This is my first line.
This is second line.

Polecenie, które próbowałem:

:%s/\n/\n\n/g

zastępuje ciąg niechcianymi znakami jak

This is my first line.^@^@This is second line.^@^@

Następnie wypróbowałem następujące polecenie

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

Działa poprawnie. Czy możesz wyjaśnić, dlaczego działa dobrze z drugim poleceniem?

Raghvendra
źródło
Zobacz także unix.stackexchange.com/a/206404
Stéphane Chazelas
2
FYI: Istnieje również Vi i Vim (beta) SE .
Dubu,
2
Na marginesie, nie musisz używać /jako separatora. Jest to bardziej czytelne::%s;\n;\n\n;g
DJMcMayhem,
1
Szukaj \n, wymień \r\r, :% s/\n/\r\r/g: stackoverflow.com/a/71334/911945
Anton Tarasenko

Odpowiedzi:

47

Co dziwne, \nw vimie zamiana nie oznacza nowej linii, ale zero. ASCII nul is ^@( control@).

Historycznie, vi zastępuje ^M( controlM) jako koniec linii, który jest nową linią. vim dodał rozszerzenie \r(podobnie jak język C), aby oznaczać to samo co ^M, ale programiści postanowili nadać mu \nwartość null podczas zamiany tekstu. Jest to niespójne z jego użyciem w wyszukiwaniu , które znajduje nowy wiersz.

Dalsza lektura:

Thomas Dickey
źródło
7

Spróbuj tego: %s/$/^V^M/(gdzie ^Vjest Ctrl-Vi ^Mjest Ctrl-M- po wpisaniu ^Vwypisuje ^znak, a następnie backspace nad nim, a po wpisaniu ^Mpojawi się jako ^M... Ctrl-V jest standardowym dosłownym znakiem tty - uruchom polecenie, stty -aaby pokaż znaki specjalne swojego tty).

Murray Jensen
źródło
Rzeczywiście, bardzo doświadczeni będą to wiedzieć o zawsze wymaganej konwersji z CRLF jako alternatywy dla rezygnacji i używania dos2unix lub podobnego. Korzystanie z Ctrl-V to lekcja dnia 1 vi.
mckenzm,
5

vimsłuży \ndo reprezentowania znaku pustego \0w pamięci, że sposób vimobsługi pliku zawiera znak pusty (chociaż vinie może).

Użycie \nw wyrażeniu tylko pasującego końca linii w buforze, a nie nowego wiersza w ciągu.

Patrz : h NL-używany-dla-Null i : h CR-używany-dla-NL po więcej szczegółów.

Cuonglm
źródło
1

Testowane z Neovim ( nvim) i Vimwersjami

NVIM v0.3.0
VIM - Vi IMproved 8.1

Usuń nowy wiersz:

cell
allele
rs2981578
fgfr2

Tutaj \ndopasowuje znaki nowej linii (aby wstawić nową linię, użyj \r):

:'<,'>s/\n/|/g

cell|allele|rs2981578|fgfr2

Dodaj nowy wiersz:

Nie:

cell|allele|rs2981578|fgfr2

:'<,'>s/\n/|/g

cell^@allele^@rs2981578^@fgfr2

^@jest znakiem diakrytycznym dla LF (wysuw wiersza; patrz http://vimhelp.appspot.com/digraph.txt.html#digraphs-default )

Tak:

cell|allele|rs2981578|fgfr2

:'<,'>s/|/\r/g

cell
allele
rs2981578
fgfr2

Aby odpowiedzieć na pytanie PO (jak zamienić jeden na \ndwa \n\n), wystarczy dodać kolejne \r:

cell
allele
rs2981578
fgfr2

:'<,'>s/\n/\r\r/g

cell

allele

rs2981578

fgfr2

... tj. dopasuj oryginalny \nznak nowej linii ( ) i zastąp go dwoma znakami nowej linii / znaku powrotu karetki ( \r\r).

Victoria Stuart
źródło