Jak zamienić znak na nowy wiersz w Vimie


1967

Próbuję zastąpić każdy ,w bieżącym pliku nowym wierszem:

:%s/,/\n/g 

Ale wstawia coś, co wygląda jak ^@rzeczywista nowa linia. Plik nie jest w trybie DOS ani nic takiego.

Co powinienem zrobić?

Jeśli jesteś ciekawy, tak jak ja, sprawdź pytanie: Dlaczego jest nowy wiersz dla Vima? także.


2
Stack Overflow to strona z pytaniami dotyczącymi programowania i programowania. To pytanie wydaje się być nie na temat, ponieważ nie dotyczy programowania ani programowania. Zobacz o jakie tematy mogę pytać tutaj w Centrum pomocy. Być może lepiej byłoby zapytać Super User lub Unix & Linux Stack Exchange .
jww

5
@ jww to pytanie ma 10 lat ... wydaje się, że jest za stare, aby migrować. Jest wiele takich pytań, na przykład: stackoverflow.com/questions/10175812/...
Vinko Vrsalovic

14
@ jww vim jest narzędziem często używanym przez programistów, a pytania dotyczące narzędzi często używanych przez programistów są na temat w przepełnieniu stosu . Chociaż oczywiście jest to bardziej odpowiednie dla Vi i Vima .
user202729,

Odpowiedzi:


2565

Użyj \rzamiast \n.

Zastąpienie przez \nwstawia znak pusty w tekście. Aby uzyskać nowy wiersz, użyj \r. Jednak podczas wyszukiwania nowego wiersza nadal będziesz używać \n. Ta asymetria wynika z faktu, że \ni \r robią nieco inne rzeczy :

\ndopasowuje koniec linii (nowa linia), natomiast \rdopasowuje znak powrotu karetki. Z drugiej strony, w podstawieniach \nwstawia znak zerowy, a \rwstawia znak nowej linii (a dokładniej, jest traktowany jako dane wejściowe <CR>). Oto mały, nieinteraktywny przykład, aby to zilustrować, przy użyciu funkcji wiersza polecenia Vima (innymi słowy, możesz skopiować i wkleić poniższe w terminalu, aby go uruchomić). xxdpokazuje zrzut heksowy wynikowego pliku.

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.

Innymi słowy, \nwstawił bajt 0x00 do tekstu; \rwstawił bajt 0x0a.


127
/ r jest traktowane jako naciśnięcie klawisza Enter / Return. Działa na wszystkich platformach.
Luka Marinko,


14
Chciałbym, żeby to działało w przypadku klasycznego vi. W systemie AIX 6.1 \rnie działa w ten sposób. Ale możesz naciskać Ctrl-V Enterzamiast pisać \ri to działa.
eksortso

3
Jestem spóźniony na przyjęcie. Jeśli \rwstawia <CR>i \nwstawia wartość zerową, w jaki sposób miałbym zastąpić coś znakiem powrotu karetki?
Pan Llama,

2
@SunnyRaj czy jesteś pewien historii CR i LF? Miałem wrażenie, że pierwotnie LF przesunął papier o jeden rząd do przodu, ale nie przesunął głowicy drukującej, a CR przesunął głowicę drukującą, ale nie przesunął papieru. W rezultacie, jeśli Twój system operacyjny nie przekonwertował danych wejściowych przed drukowaniem, nie możesz użyć tylko LF ani CR, aby uzyskać prawidłowe dane wyjściowe. MS DOS użył surowych danych drukarki jako formatu pliku tekstowego, Mac OS użył CR i przekonwertował z tego na surowy format drukarki, a UNIX użył LF i przekonwertował z tego na surowy format drukarki.
Mikko Rantalainen,

210

Oto sztuczka:

Najpierw ustaw swoją sesję Vi (m), aby umożliwić dopasowanie wzorca ze znakami specjalnymi (np. Nowa linia). Prawdopodobnie warto umieścić tę linię w pliku .vimrc lub .exrc:

:set magic

Następnie wykonaj:

:s/,/,^M/g

Aby zdobyć ^Mpostać, wpisz Ctrl+ Vi naciśnij Enter. Pod Windows, wykonaj Ctrl+ Q, Enter. Jedyny sposób, w jaki mogę je zapamiętać, to zapamiętanie, jak mało mają sensu:

Odp .: Jaki byłby najgorszy znak kontrolny, którego można użyć do przedstawienia nowej linii?

B: Albo q(ponieważ zwykle oznacza to „Wyjdź”) albo vdlatego, że tak łatwo byłoby wpisać Ctrl+ Cprzez pomyłkę i zabić edytora.

Odp .: Zrób to.


9
Korzystam z GVim na Windowsie i nie potrzebuję ani :set magic(nie ma go w moim ~ / _vimrc), ani ctrl-q. Wystarczy proste, ctrl-va następnie Enter tworzy ^Mdla mnie postać w porządku.
Chris Phillips

5
Cv nie reprezentuje nowego wiersza; jest to polecenie „uciekaj od następnej dosłownej postaci”. Nie wiem, po co Cv jest mnemonikiem, ale istnieje powód, dla którego nie mentalnie mapuje na nową linię.
Jim Stewart

27
Ctrl-v jest mnemonikiem dla słowa „dosłownie” - tzn. Unika następnego klawisza wciśniętego na jego kod / znak „dosłownie”. W systemie Windows jest to wklej: aby zachować znajomość. Ctrl-Q może oznaczać „(un) Quote”. W każdym razie dość głupie - ale można go używać w plikach binarnych - np. Do szukania Ctrl-A przez Ctrl-Z (chyba Ascii 1-26).
Tomasz Gandor

1
Ctrl-Ctak naprawdę nie zabija edytora, chociaż może anulować powrót do trybu normalnego. Ctrl-Voznacza dosłownie i Ctrl-Qoznacza, że ​​ktoś popełnił błąd podczas ładowania $VIMRUNTIME/mswin.vimpliku konfiguracyjnego. Nie potrzebujesz MSWIN. Zamiast tego użyj własnego vimrc.
00dani

WOW, to jest niesamowite. Robiłem do sed -n l tej pory. Dobrze wiedzieć, że to samo można osiągnąć za pomocą Ctrl-vin vim.
arpit

98

W składni s/foo/bar, \ri \nmają różne znaczenie w zależności od kontekstu.


Krótki:

Dla foo:

\ n = nowa linia (LF w systemie Linux / Mac, CR + LF w systemie Windows)
\ r = powrót karetki (CR)

Dla bar:

\ r = jest znakiem nowej linii
\ n = bajt zerowy.

Dłuższy (z numerami ASCII):

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

Oto lista znaków kontrolnych ASCII . Wstaw je do Vima za pomocą Ctrl+ V, Ctrl+ ---key---.

W Bash lub innych powłokach Unix / Linux po prostu wpisz Ctrl+ ---key---.

Spróbuj Ctrl+ Mw Bash. Jest to to samo, co uderzenie Enter, ponieważ powłoka zdaje sobie sprawę z tego, co ma na myśli, nawet jeśli systemy Linux używają kanałów do rozdzielania linii.

Aby wstawić literały w bash, dodanie ich za pomocą Ctrl+ Vrównież będzie działać.

Wypróbuj w Bash:

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

Wykorzystuje sekwencje specjalne ANSI . Włóż dwa ^[„s poprzez Ctrl+ V, Esc.

Można także spróbować Ctrl+ V, Ctrl+ M, Enter, który pozwoli Ci dać w ten sposób:

bash: $'\r': command not found

Pamiętasz \rz góry? :>

Ta lista znaków kontrolnych ASCII różni się od kompletnej tablicy symboli ASCII tym , że można tam znaleźć znaki kontrolne, które są wstawiane do konsoli / pseudoterminalu / Vima za pomocą Ctrlklucza (haha).

Podczas gdy w C i większości innych języków zwykle używasz kodów ósemkowych do reprezentowania tych „znaków”.

Jeśli naprawdę chcesz wiedzieć, skąd to wszystko się bierze: TTY odszyfrowane . To jest najlepszy link do tego tematu, ale uważaj: są smoki.


TL; DR

Zwykle foo= \ni bar= \r.


1
Intryguje mnie to, jak zastąpiłbyś postać znakiem powrotu karetki
codehot

2
@codeshot :s/x/^M/gpowinien zrobić. Wstaw ^Mvia, ctrl-va następnie ctrl-m.
sjas,

3
Dzięki sjas, wiesz, że to pytanie jest jednym z najdziwniejszych wszechczasów. 1008 głosów za odpowiedzią, która w zasadzie mówi tylko „vim robi to, co znalazłeś. To dlatego, że vim robi to, co znalazłeś. Nigdy nie zapominaj, że vim robi to, co znalazłeś”. Miałem nadzieję znaleźć krótką listę kodów dla interesujących znaków we wzorze, zamiennik i przyczynę dziwności, więc łatwo ją zapamiętać i przewidzieć inną podobną dziwność. To miałoby mój głos.
codhot

@codeshot lista znaków kontrolnych ascii może ci pomóc. Zobacz cs.tut.fi/~jkorpela/chars/c0.html w celu uzyskania dalszych informacji. Zaktualizuję moją odpowiedź, aby zawierała dwa linki.
sjas,

55

Musisz użyć:

:%s/,/^M/g

Aby uzyskać ^Mpostać, naciśnij Ctrl+, va następnie Enter.


4
Muszę zrobić <Cv> <Cm>, aby uzyskać znak ^ M.
Jezen Thomas



16

To najlepsza odpowiedź dla mojego sposobu myślenia, ale byłaby ładniejsza w tabeli:

Dlaczego nowa linia dla Vima?

Przeredagowanie:

Musisz użyć, \raby użyć przejścia do wiersza (ASCII 0x0A, nowa linia uniksowa) w zamianie wyrażenia regularnego, ale jest to specyficzne dla zamiany - zwykle powinieneś nadal oczekiwać, że użyjesz go \ndo przesunięcia wiersza i \rpowrotu karetki.

Wynika to z tego, że Vim używał \nzamiennika w znaczeniu znaku NIL (ASCII 0x00). Być może spodziewałeś się, że NIL był \0zamiast tego, zwalniając go \ndo zwykłego użycia do wstawiania wiersza, ale \0już ma znaczenie w zastępowaniu wyrażeń regularnych, więc został przesunięty do \n. Stąd dalej idzie również przesunięcie nowej linii z \nna \r(która we wzorcu wyrażenia regularnego jest znakiem powrotu karetki, ASCII 0x0D).

Charakter | Kod ASCII | Reprezentacja C | Regex match | Wymiana Regex
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
zero | 0x00 | \ 0 | \ 0 | \ n
nowy wiersz (nowa linia uniksowa) | 0x0a | \ n | \ n | r
powrót karetki | 0x0d | \ r | \ r | <unnown>

Uwaga: ^M( Ctrl+ V Ctrl+ Mw systemie Linux) wstawia nowy wiersz, gdy jest używany w zamianie wyrażenia regularnego, zamiast powrotu karetki, jak zalecili inni (właśnie tego próbowałem).

Zauważ też, że Vim przetłumaczy znak przesunięcia wiersza, gdy zapisuje do pliku na podstawie ustawień formatu pliku, co może mylić sprawy.



8

Ale jeśli trzeba zastąpić, to działa następująca rzecz:

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

W powyższym, każda następna linia jest zastępowana następną linią, a następnie |-raz za razem nową linią. Jest to używane w tabelach wiki.

Jeśli tekst jest następujący:

line1
line2
line3

Zmienia się na

line1
|-
line2
|-
line3

7

Jeśli musisz to zrobić dla całego pliku, zasugerowano mi również, że możesz spróbować z wiersza poleceń:

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

1
Zauważ, że wymaga to GNU sed. Spróbuj printf 'foo\\nbar\n' | sed 's/\\n/\n/g'sprawdzić, czy zadziała w twoim systemie. (Podziękowania dla dobrych ludzi z #bash na freenode za tę sugestię).
Evan Donovan,

Tak, ale pytanie dotyczyło Vima. Jest pytanie Przepełnienie stosu Jak mogę zastąpić nowy wiersz (\ n) za pomocą sed? .
Peter Mortensen

5

Oto odpowiedź, która zadziałała dla mnie. Od tego faceta:

---- cytowanie Użyj edytora vi, aby wstawić znak nowej linii w miejsce zamiany


Coś jeszcze muszę zrobić i nie mogę sobie przypomnieć, a potem muszę podnieść wzrok.

W vi, aby wstawić znak nowej linii do wyszukiwania i zamień, wykonaj następujące czynności:

:%s/look_for/replace_with^M/g

Powyższe polecenie zastąpiłoby wszystkie wystąpienia „look_for” na „replace_with \ n” (z \ n oznacza nowy wiersz).

Aby uzyskać „^ M”, wprowadź kombinację klawiszy Ctrl+ V, a następnie (zwolnij wszystkie klawisze) naciśnij Enterklawisz.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.