Linux удалить символ переноса строки

How can I replace each newline (\n) with a space using sed?

How can I replace a newline (» \n «) with a space (» «) using the sed command? I unsuccessfully tried:

sed 's#\n# #g' file sed 's#^$# #g' file 

tr is only the right tool for the job if replace a single character for a single character, while the example above shows replace newline with a space.. So in the above example, tr could work.. But would be limiting later on.

tr in the right tool for the job because the questioner wanted to replace each newline with a space, as shown in his example. The replacement of newlines is uniquely arcane for sed but easily done by tr . This is a common question. Performing regex replacements is not done by tr but by sed , which would be the right tool. for a different question.

«tr» can also just delete the newline ` tr -d ‘\n’ ` however you may also like to delete returns to be more universal ` tr -d ‘\012\015’ `.

WARNING: «tr» acts differently with regards to a character ranges between Linux and older Solaris machines (EG sol5.8). EG: ` tr -d ‘a-z’ ` and ` tr -d ‘[a-z]’ `. For that I recommend you use «sed» which doesn’t have that difference.

@MikeS Thanks for the answer. Follow tr ‘\012’ ‘ ‘ with an echo . Otherwise the last linefeed in the file is deleted, too. tr ‘\012’ ‘ ‘ < filename; echo does the trick.

43 Answers 43

sed is intended to be used on line-based input. Although it can do what you need.

A better option here is to use the tr command as follows:

or remove the newline characters entirely:

or if you have the GNU version (with its long options)

sed works on a «stream» of input, but it comprehends it in newline delimited chunks. It is a unix tool, which means it does one thing very well. The one thing is «work on a file line-wise». Making it do something else will be hard, and risks being buggy. The moral of the story is: choose the right tool. A great many of your questions seem to take the form «How can I make this tool do something it was never meant to do?» Those questions are interesting, but if they come up in the course of solving a real problem, you’re probably doing it wrong.

tr only works with one character strings. You can’t replace all new lines with a string that is multiple characters long.

Use this solution with GNU sed :

This will read the whole file in a loop ( ‘:a;N;$!ba ), then replaces the newline(s) with a space ( s/\n/ /g ). Additional substitutions can be simply appended if needed.

  1. sed starts by reading the first line excluding the newline into the pattern space.
  2. Create a label via :a .
  3. Append a newline and next line to the pattern space via N .
  4. If we are before the last line, branch to the created label $!ba ( $! means not to do it on the last line. This is necessary to avoid executing N again, which would terminate the script if there is no more input!).
  5. Finally the substitution replaces every newline with a space on the pattern space (which is the whole file).
Читайте также:  Command line tar linux

Here is cross-platform compatible syntax which works with BSD and OS X’s sed (as per @Benjie comment):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file 

As you can see, using sed for this otherwise simple problem is problematic. For a simpler and adequate solution see this answer.

You can run this cross-platform (i.e. on Mac OS X) by separately executing the commands rather than separating with semi-colons: sed -e ‘:a’ -e ‘N’ -e ‘$!ba’ -e ‘s/\n/ /g’

See number 3 above. It seems that $! means not to do it on the last line as there should be one final newline.

This is an impressive answer. I also find it ironic that Linux tools are supposed to be «do one thing well» when it seems like most Linux tools do many things, poorly

echo «Hello\nWorld» | sed -e ‘:a’ -e ‘N’ -e ‘$!ba’ -e ‘s/\n/ /g’ returns «Hello World», but echo «Hello World» | sed -e ‘:a’ -e ‘N’ -e ‘$!ba’ -e ‘s/\n/ /g’ returns an empty string for me. I’m on MacOS Big Sur.

Fast answer

sed will loop through step 1 to 3 until it reach the last line, getting all lines fit in the pattern space where sed will substitute all \n characters

Alternatives

All alternatives, unlike sed will not need to reach the last line to begin the process

with bash, slow

while read line; do printf "%s" "$line "; done < file 

with perl, sed-like speed

with tr, faster than sed, can replace by one character only

with paste, tr-like speed, can replace by one character only

with awk, tr-like speed

Other alternative like "echo $( < file)"is slow, works only on small files and needs to process the whole file to begin the process.

Long answer from the sed FAQ 5.10

5.10. Why can't I match or delete a newline using the \n escape
sequence? Why can't I match 2 or more lines using \n?

The \n will never match the newline at the end-of-line because the
newline is always stripped off before the line is placed into the
pattern space. To get 2 or more lines into the pattern space, use
the 'N' command or something similar (such as 'H;. ;g;').

Sed works like this: sed reads one line at a time, chops off the
terminating newline, puts what is left into the pattern space where
the sed script can address or change it, and when the pattern space
is printed, appends a newline to stdout (or to a file). If the
pattern space is entirely or partially deleted with 'd' or 'D', the
newline is not added in such cases. Thus, scripts like

 sed 's/\n//' file # to delete newlines from each line sed 's/\n/foo\n/' file # to add a word to the end of each line 

will NEVER work, because the trailing newline is removed before
the line is put into the pattern space. To perform the above tasks,
use one of these scripts instead:

Читайте также:  Linux clear all screen

Since versions of sed other than GNU sed have limits to the size of
the pattern buffer, the Unix 'tr' utility is to be preferred here.
If the last line of the file contains a newline, GNU sed will add
that newline to the output but delete all others, whereas tr will
delete all newlines.

To match a block of two or more lines, there are 3 basic choices:
(1) use the 'N' command to add the Next line to the pattern space;
(2) use the 'H' command at least twice to append the current line
to the Hold space, and then retrieve the lines from the hold space
with x, g, or G; or (3) use address ranges (see section 3.3, above)
to match lines between two specified addresses.

Choices (1) and (2) will put an \n into the pattern space, where it
can be addressed as desired ('s/ABC\nXYZ/alphabet/g'). One example
of using 'N' to delete a block of lines appears in section 4.13
("How do I delete a block of specific consecutive lines?"). This
example can be modified by changing the delete command to something
else, like 'p' (print), 'i' (insert), 'c' (change), 'a' (append),
or 's' (substitute).

Choice (3) will not put an \n into the pattern space, but it does
match a block of consecutive lines, so it may be that you don't
even need the \n to find what you're looking for. Since GNU sed
version 3.02.80 now supports this syntax:

 sed '/start/,+4d' # to delete "start" plus the next 4 lines, 

in addition to the traditional '/from here/,/to there/<. >' range
addresses, it may be possible to avoid the use of \n entirely.

Источник

Как убрать перенос строк с помощью sed?

illifant и mm3 большое спасибо. Ваши ответы очень помогли.

если нужно удалить все \n, то проще использовать

А зачем там «/$/N» вместо просто «N»?

Тема обсосана на stackoverflow.

Мёсье не осилил увидеть команды : и t на видном месте в мане, и теперь со всех требует прув, не допуская существования более вдумчивых людей?

без понятия что означают все эти 20 символов (объяснил бы хоть кто), но они работают.

Здесь куча способов удалить '\n' на разных языках.

Эти? 1) метка 2) добавляем к текущей строке сдедующую (через \n) 3) удаляем разделитель 3) если команда s/// что-то сделала - переходим на метку.

Видно, что /$/ - лишний, но /../ может пригодиться, например: /\\$/.

Похожие темы

  • Форум всемогущий sed (2017)
  • Форум sed vs awk (2008)
  • Форум Удалить последнее слово в строке awk, sed (2014)
  • Форум sed диапазон строк (2013)
  • Форум Как с помощью sed вставить в конец каждой строки файла апостроф? (2022)
  • Форум Оптимизировать sed разбивку файла (2020)
  • Форум Разделитель ascii для sed и awk (2015)
  • Форум awk и sed (2011)
  • Форум Sed (вырезать подстроки из строки) (2012)
  • Форум Книги по AWK, SED (2013)
Читайте также:  Pro linux операционная система

Источник

Удаление знаков переноса строки в bash

Регулярка извлекает с файла кусок многострочного текста. Следующая задача - получить из него одну строку. Попробовал sed "s/\r\n//" . Комбинации опробованы различные. Гуглю различные вариации обозначения знака переноса, не получается. За направление правильного гуления скажу большое спасибо ). текст - utf-8.

stroka3 stroka2 stroka1 stroka1 stroka2 stroka3 - результат \n разнообразно опробован и без результата. различные флаги sed и tr

Что-то вы делаете не так 🙂 $ cat in.txt stroka3 stroka2 stroka1 stroka1 stroka2 stroka3 $ cat in.txt | tr -s '\r\n' ' ' stroka3 stroka2 stroka1 stroka1 stroka2 stroka3 $ cat in.txt | tr -d '\r\n' stroka3stroka2stroka1stroka1stroka2stroka3

3 ответа 3

cat in.txt | tr -s '\r\n' ' ' > out.txt 

Или, если склеить строки (в примере выше \r\n меняется на пробел):

cat in.txt | tr -d '\r\n' > out.txt 

P.S. '\r\n' меняем на '\n' для unix-переводов строк.

смотрим содержимое файла in.txt ~ $ cat in.txt stroka3

stroka2 stroka1 stroka1 stroka2 stroka3 

загоняем всё что в файле в переменную

с помощью echo выводим содержимое переменной

~ $ echo "$string" # переменная в кавычках выдаст с переносами строк stroka3 stroka2 stroka1 stroka1 stroka2 stroka3 ~ $ echo $string # переменная БЕЗ кавычкех выдаст БЕЗ переносов строк stroka3 stroka2 stroka1 stroka1 stroka2 stroka3 

Источник

Удаление знаков переноса с возвратом строки

при выгрузке случился баг и после data3 добавился знак переноса строки \n и все сьехало на две строки. data3 обрамлен " (двойные ковычки) файл очень большой 1 мил строк и в ручную не вариант переделывать подскажите как через sed убрать перенос строки для того чтобы сьехавший хвост вытянулся в одну строку сейчас файл имеет такой вид

data1,data2,"data3 ",data4 data1,data2,"data3 ",data4 data1,data2,"data3 ",data4 
data1,data2,"data3",data4 data1,data2,"data3",data4 data1,data2,"data3",data4 

4 ответа 4

[VladD@Kenga] [00:59:25] [~] $> cat xx.txt data1,data2,"data3 ",data4 data1,data2,"data3 ",data4 data1,data2,"data3 ",data4 [VladD@Kenga] [00:59:32] [~] $> sed 'N;s/\n"/"/' xx.txt data1,data2,"data3",data4 data1,data2,"data3",data4 data1,data2,"data3",data4 

Для более сложных случаев (возможны «обыкновенные» строки) попробуйте так:

[VladD@Kenga] [01:35:47] [~] $> cat xx.txt header "data1",data2,"data3 ",data4 intermediate data data1,"data2 ","data3 ",data4 data1,data2,"data3 ",data4 [VladD@Kenga] [01:35:52] [~] $> sed '/^",/; x' xx.txt header "data1",data2,"data3",data4 intermediate data data1,"data2","data3",data4 data1,data2,"data3",data4 [VladD@Kenga] [01:35:57] [~] $> sed '/^",/; x' xx.txt | sed '1d' header "data1",data2,"data3",data4 intermediate data data1,"data2","data3",data4 data1,data2,"data3",data4 

Внимение: последняя строка должна заканчиваться переводом строки, иначе она будет «проглочена»!

Объяснение: нам необходимо, когда мы видим строку, начинающуюся с кавычки, знать предыдущую строку, чтобы склеить их. Для этого мы «задерживаем» вывод строк, отправляя их в hold space вместо вывода, и выводя вместо этого предыдущую строку, лежащую там же ( x ).

Для случая, когда строка начинается с кавычки ( /^"/ ) начинаем действовать. В hold space лежит предыдущая строка, пристыковываем к ней текущую ( H ), и обмениваем hold space с pattern space ( x ), чтобы можно было обработать текст. Удаляем \n ( s/\n// ), и отправляем назад строку в hold space, чтобы проанализировать и вывести её на следующем цикле. Обрубок строки, который получился в pattern space, удаляем, и завершаем эту итерацию ( d ).

Источник

Оцените статью
Adblock
detector