Что такое символ перевода строки - '\ n' - PullRequest
9 голосов
/ 16 июля 2010

Это очень базовая концепция, но я никогда не мог сформулировать это так хорошо. и я хотел бы попытаться записать это по буквам и посмотреть, где я ошибаюсь.

Если мне нужно, как бы я определил «символ новой строки». скажем, если я создаю новый файл в Unix (или Windows), то сохраняет ли файл информацию «конца строки», вставляя специальный символ в файл, называемый «символ новой строки». Если да, то какова его ценность для ascii? Я помню, что в программах на C я проверял наличие символа чтения по значению '\ n'. И почему это сбивает с толку 2 символа для представления символов конца строки ..

bash$ cat states
California
Massachusetts
Arizona

Скажем, я хочу вставить одну строку между строками и хочу вывод в виде: Желаемый вывод:

California

Massachusetts

Arizona

bash$sed -e 's/\n/\n\n/g' states  does not work.

Почему я не могу обработать «символ новой строки» здесь так же, как я бы обработал любой другой символ и выполнил что-то вроде вышеуказанной команды. (Я понимаю, что можно сказать, что это вопрос синтаксиса sed, но не могли бы вы объяснить интуицию, стоящую за этим, чтобы я мог избавиться от своего замешательства.

Аналогично, в редакторе vim я не могу использовать:% s / \ n / \ n \ n / g. Почему так?

Нужно ли мне продолжать экранировать \ n, используя обратную косую черту в sed и из vim?

Спасибо

Jagrati

Ответы [ 8 ]

11 голосов
/ 16 июля 2010

Из справочной страницы sed :

Обычно sed циклически копирует строку ввода, не включая ее завершающий символ новой строки, в пространство шаблона (если после функции "D" не осталось ничего), применяет все команды с адресами, которые выбирают этот шаблон пробел, копирует пространство шаблона в стандартный вывод, добавляя новую строку и удаляя пространство шаблона.

Он работает в строке без присутствия символа новой строки, поэтому шаблон, который у вас есть, не может соответствовать. Вам нужно сделать что-то еще - например, сопоставление с $ (конец строки) или ^ (начало строки).

Вот пример того, что сработало для меня:

$ cat > states
California
Massachusetts
Arizona
$ sed -e 's/$/\
> /' states
California

Massachusetts

Arizona

Я набрал буквальный символ новой строки после \ в строке sed.

11 голосов
/ 16 июля 2010

NewLine (\ n) - 10 (0xA), а CarriageReturn (\ r) - 13 (0xD).

Различные операционные системы выбирали разные представления конца строки для файлов.Windows использует CRLF (\ r \ n).Unix использует LF (\ n).В старых версиях Mac OS используется CR (\ r), но OS X переключается на символ Unix.

Вот относительно полезный FAQ .

5 голосов
/ 16 июля 2010

Символы Escape зависят от того, какая система их интерпретирует.\n интерпретируется как символ новой строки во многих языках программирования, но это не обязательно относится к другим упомянутым вами утилитам.Даже если они воспринимают \n как символ новой строки, могут существовать и другие методы, позволяющие им вести себя так, как вы хотите.Вам придется ознакомиться с их документацией (или посмотреть другие ответы здесь).

Для систем DOS / Windows символ новой строки фактически состоит из двух символов: возврат каретки (ASCII 13, AKA \r), за которым следует перевод строки(ASCII 10).В системах Unix (включая Mac OSX) это просто перевод строки.На старых Mac это был единственный возврат каретки.

3 голосов
/ 16 июля 2010
sed 's/$/\n/' states
1 голос
/ 06 декабря 2013

sed можно перевести в режим многострочного поиска и замены для соответствия символам новой строки \n.

Для этого sed сначала должен прочитать весь файл или строку в буфер хранения(«удерживать пробел»), чтобы он мог обрабатывать содержимое файла или строки как одну строку в «пробел».

Чтобы заменить одну переносимую строку переносно (по отношению к GNU и FreeBSD sed), вы можете использовать экранированный "настоящий" перевод строки.

# cf. http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
echo 'California
Massachusetts
Arizona' | 
sed -n -e '
# if the first line copy the pattern to the hold buffer
1h
# if not the first line then append the pattern to the hold buffer
1!H
# if the last line then ...
$ {
# copy from the hold to the pattern buffer
g
# double newlines
s/\n/\
\
/g
s/$/\
/
p
}'

# output
# California
#
# Massachusetts
#
# Arizona
#

Однако существует гораздо большеудобно было добиться того же результата:

echo 'California
Massachusetts
Arizona' | 
   sed G
1 голос
/ 16 июля 2010

Я думаю, эта запись Джеффа Этвуда идеально ответит на ваш вопрос.Он проведет вас через различия между новыми строками на Dos, Mac и Unix, а затем объяснит историю CR (возврат каретки) и LF (перевод строки).

0 голосов
/ 24 декабря 2013

Я вижу много ответов sed, но ни одного для vim.Честно говоря, обращение с символами новой строки в vim немного сбивает с толку.Найдите \ n , но замените на \ r .Я рекомендую RTFM: :help pattern в целом и :help NL-used-for-Nul в частности.

Чтобы делать то, что вы хотите, с помощью команды: замещать,

:%s/\_$/\r

, хотя я думаю, что большинство людей будут использовать что-тонапример

:g/^/put=''

за тот же эффект.

Вот способ найти ответ для себя.Запустите ваш файл через xxd, который является частью стандартного дистрибутива vim.

:%!xxd

Вы получите

0000000: 4361 6c69 666f 726e 6961 0a4d 6173 7361  California.Massa
0000010: 6368 7573 6574 7473 0a41 7269 7a6f 6e61  chusetts.Arizona
0000020: 0a                                       .

Это показывает, что 46 - это шестнадцатеричный код для C , 61 - это код a и т. Д.В частности, 0a (десятичное 10) - это код для \ n .Просто для удовольствия попробуйте

:set ff=dos

перед фильтрацией через xxd.Вы увидите 0d0a (CRLF) в качестве ограничителя строки.

:help /\_$
:help :g
:help :put
:help :!
:help 23.4
0 голосов
/ 16 июля 2010

Попробуйте это:

$ sed -e $'s/\n/\n\n/g' states
...