Pytanie Jak zastąpić znak przez znak nowej linii w Vim?


Próbuję zastąpić każdą , w bieżącym pliku przez nową linię:

:%s/,/\n/g 

Ale wstawia to, co wygląda jak ^@ zamiast faktycznego nowego wiersza. Plik nie jest w trybie DOS ani nic.

Co powinienem zrobić?

Jeśli jesteś ciekawy, jak ja, sprawdź pytanie Dlaczego \ r jest nowym znakiem dla Vima? także.


1591
2017-09-16 11:19


pochodzenie


Stack Overflow to strona z pytaniami dotyczącymi programowania i programowania. To pytanie wydaje się być nie na temat, ponieważ nie chodzi o programowanie czy rozwój. Widzieć O jakich tematach mogę tutaj zapytać w Centrum pomocy. Być może Superużytkownik lub Unix i Linux Stack Exchange byłoby lepszym miejscem do zapytania. - jww
@jww to pytanie ma 10 lat ... wydaje się być zbyt stary, aby migrować. Istnieje wiele takich pytań, na przykład: stackoverflow.com/questions/10175812/... - Vinko Vrsalovic


Odpowiedzi:


Posługiwać się \r zamiast \n.

Zastępowanie przez \n wstawia znak null do tekstu. Aby uzyskać znak nowej linii, użyj \r. Gdy badawczy dla newline nadal będziesz używał \n, jednak. Ta asymetria wynika z faktu, że \n i \r  robić trochę inne rzeczy:

\n dopasowuje koniec linii (nowa linia), natomiast \r dopasowuje powrót karetki. Z drugiej strony, w zastępstwach \n wstawia znak null, podczas gdy \r wstawia znak nowej linii (dokładniej traktowany jest jako dane wejściowe <CR>). Oto mały, nieinteraktywny przykład do zilustrowania tego, używając funkcji wiersza poleceń Vima (innymi słowy, możesz skopiować i wkleić następujące elementy do terminala, aby go uruchomić). xxd pokazuje 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, \n wstawił bajt 0x00 do tekstu; \r wstawił bajt 0x0a.


2076
2017-09-16 11:21



dlaczego to działa w ten sposób? - Vinko Vrsalovic
/ r jest traktowane jako naciśnięcie klawisza Enter / Return. Działa na wszystkich platformach. - Luka Marinko
z dowolnego powodu, zastępując wszystkie "\ n", \ n działa podczas wykonywania:% s / '\ n /', \ r / g - tipu
Zobacz też Dlaczego \ r jest nowym znakiem dla Vima?. - Andrew Marshall
Chciałbym, żeby to działało na klasyczne vi. W systemie AIX 6.1. \r nie działa w ten sposób. Ale możesz nacisnąć Ctrl-V  Enter zamiast pisania \ri to działa. - eksortso


Oto sztuczka:

Najpierw ustaw swoją sesję vi (m), aby umożliwić dopasowywanie wzorców 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 uzyskać ^M postać, typ Kontrola-v i uderz Wchodzić. W systemie Windows, wykonaj Kontrola-q, Wchodzić. Jedyny sposób, w jaki mogę je zapamiętać, to pamiętanie, jak mało mają one sensu:

ZA: Jaki byłby najgorszy ze znaków kontrolnych, który mógłby posłużyć do przedstawienia nowej linii?

B: Zarówno q (ponieważ zwykle oznacza "Zamknij") lub v ponieważ byłoby to łatwe do wpisania Kontrola-do przez pomyłkę i zabić redaktora.

ZA: Zrób to tak.


166
2017-09-25 23:40



Używam GVim w systemie Windows i nie potrzebuję ani :set magic (nie ma go również w moim ~ / _vimrc) lub ctrl-q. Po prostu proste ctrl-v a następnie enter tworzy ^M charakter dla mnie dobrze. - Chris Phillips
C-v nie reprezentuje nowej linii; jest to polecenie "escape next literal character". Nie wiem, co to jest C-v dla mnemoników, ale istnieje powód, dla którego nie ma on mapy mentalnej do nowej linii. - Jim Stewart
Ctrl-v jest mnemonikem "dosłownego" - tj. Klawiszem escape następnego klawisza wciśniętym do jego "dosłownego" kodu / znaku. W Windowsie to wklej: aby wszystko było znane. Ctrl-Q jest dla "(nie) cytatu" być może. Całkiem głupie, w każdym razie - ale można go używać w plikach binarnych - np. szukać Ctrl-A do Ctrl-Z (jak sądzę, 1-26). - Tomasz Gandor
Teraz muszę usunąć dodatkowe "," to polecenie wprowadziło ... - Danny Wang
Ctrl-C w rzeczywistości nie zabija edytora, chociaż może anulować powrót do trybu normalnego. Ctrl-V oznacza dosłownie, i Ctrl-Q oznacza, że ​​ktoś popełnił błąd podczas ładowania $VIMRUNTIME/mswin.vim plik konfiguracyjny. Nie potrzebujesz mswin. Po prostu użyj własnego vimrc. - 00dani


W składni s/foo/bar  \r i \n mają różne znaczenia, w zależności od kontekstu.


Dla foo:
\ n = nowa linia
\ r = CR (powrót karetki = Ctrl-M = ^ M)

Dla bar:
\ r = to znak nowej linii
\ n = bajt zerowy (0x00).


W przeszłości często zdarzały mi się pytania o takie rzeczy, a kiedyś w przyszłości prawie nikt nie będzie wiedział o tych rzeczach w końcu ...

Według "popularnego" żądania:

Oto lista Znaki sterujące ASCII, włóż je vim przez CTRLvCTRL---klawisz---.
W bash lub inne powłoki unix / linux po prostu wpisz CTRL---klawisz---. Próbować CTRLM w bash, to samo co uderzenie WCHODZIĆ, ponieważ powłoka zdaje sobie sprawę z tego, co rozumiemy, mimo że systemy linux używają Line Feeds do wyznaczania linii. Tylko znak kontrolny dla Line Feed CTRL-A, który jest związany z "skokiem do początku linii" w bash.

Aby wstawić literał w bashu, CTRLv również zadziała.

Spróbuj w bash:

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

To wykorzystuje Sekwencje specjalne ANSI, włóż dwa ^[jest via CTRLvWYJŚCIE.

Możesz także spróbować CTRLvCTRLmWCHODZIĆ, która da ci to:

bash: $'\r': command not found

Zapamiętaj \r z góry? :>

The Znaki sterujące ASCII lista różni się od standardu tablica symboli ascii, w tym znaki kontrolne, które są wstawiane do konsoli / pseudoterminal / vim przez CTRL klucz (haha), można tam znaleźć. Podczas gdy w C i większości innych języków zazwyczaj używasz ósemkowych kodów do reprezentowania tych "znaków".

Jeśli naprawdę chcesz wiedzieć, skąd to wszystko pochodzi: http://www.linusakesson.net/programming/tty/.
To jest najlepszy link, jaki napotkasz na ten temat, ale uwaga: są smoki.


TL; DR

Zazwyczaj foo = \n, i bar = \r.


65
2017-09-23 14:00



Jestem zaintrygowany tym, jak zastąpić znak karetką - codeshot
@codeshot :s/x/^M/g powinieneś zrobić. Wstaw znak ^M przez ctrl-v śledzony przez ctrl-m. - sjas
Dzięki sjas, Wiesz, że to pytanie jest jednym z najdziwniejszych wszechczasów. 1008 głosów za odpowiedzią, która zasadniczo mówi nic więcej niż "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ę, że znajdę krótką listę kodów dla interesujących postaci we wzorze, zamiennika i przyczyny dziwactwa, tak, że łatwo je zapamiętać i przewidzieć inne podobne dziwactwa. To by dostało mój głos. - codeshot
@codeshot lista znaków kontrolnych ASCII może ci pomóc. Widzieć cs.tut.fi/~jkorpela/chars/c0.html dla dalszego odniesienia. Zaktualizuję swoją odpowiedź, dodając dwa linki. - sjas
@codeshot Znowu zaktualizowałem post z rzeczami, które mogą Cię zainteresować. Od czasu, gdy HARD znalazł informacje na ten temat za pośrednictwem Google'a w spójnym zapisie, wydaje mi się, że blog na ten temat jest spóźniony ... - sjas


Musisz użyć

:%s/,/^M/g

Aby uzyskać ^M znak, naciśnij Ctrl  v śledzony przez Wchodzić


45
2017-09-16 11:30



Muszę wykonać <C-v> <C-m>, aby uzyskać znak ^ M. - Jezen Thomas


\r może wykonać pracę dla ciebie.


27
2017-09-16 11:21





Z Vim na Windowsie Ctrl+Q zamiast Ctrl+V


20
2017-09-16 11:45





Od zaćmienia, ^M znaki mogą być osadzone w linii i chcesz przekonwertować je na znaki nowej linii.

:s/\r/\r/g

8
2017-09-06 17:53





Ale jeśli ktoś musi zastąpić, to działa następująco

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

w powyższym każdy następny wiersz jest zastępowany przez następną linię, a następnie | - i znowu kolejną linię. Jest to używane w tabelach wiki. jeśli tekst jest następujący:

line1
line2
line3

jest zmienione na

line1
|-
line2
|-
line3

5
2018-02-07 08:09





To jest najlepsza odpowiedź na sposób, w jaki myślę, ale byłoby ładniej w tabeli: https://stackoverflow.com/a/12389839/962394.

Zatem, przeredagowując:

Musisz użyć \r aby użyć linii posuwu (ascii 0x0a, unix newline) w zastępstwie regex, ale jest to specyficzne dla zamiennika - powinieneś normalnie nadal oczekiwać użycia \n dla linii i \r dla powrotu karetki.

Jest tak dlatego, że vim był używany \n w zamienniku oznacza znak NIL (ascii 0x00). Mogłeś się spodziewać NIL \0 zamiast tego uwalniając \n do zwykłego użycia do podawania linii, ale \0 ma już znaczenie w zamiennikach regex, więc zostało przesunięte do \n. Stąd idąc dalej, również przesunąć znak nowej linii \n do \r (który w regexie to znak powrotu karetki, ascii 0x0d).

znak | kod ascii | Reprezentacja C | dopasowanie regex | zastąpienie regex
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
zero | 0x00 | \ 0 | \ 0 | \ n
line feed (unix newline) | 0x0a | \ n | \ n | \ r
powrót karetki 0x0d | \ r | \ r | <nieznany>

NB: ^M (Ctrl-V Ctrl-M na Linuksie) wstawia znak nowej linii, gdy jest używany w zastępczym regex, a nie w znaku powrotu karetki, tak jak radzili sobie inni (po prostu próbowałem).

Zauważ też, że vim przetłumaczy znak linii, kiedy zapisuje do pliku na podstawie ustawień formatu pliku, co może wprowadzać zamieszanie.


5
2018-04-08 12:15





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

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

4
2018-02-09 23:01



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