Take the 2-minute tour ×

I unsuccesfully tried:

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

How to fix it?

share|improve this question
Added tr and perl as tags, since alternative tools are acceptable to the OP. –  ire_and_curses Aug 9 '09 at 20:00
I strongly suggest using tr instead of sed as suggested in @dmckee's answer below. It's much simpler and the "right tool for the job." –  T. Brian Jones Jan 4 '13 at 6:55
add comment

31 Answers

up vote 507 down vote accepted

Or use this solution with sed:


This will read the whole file in a loop, then replaces the newline(s) with a space.

Update: explanation.

  1. create a label via :a
  2. append the current and next line to the pattern space via N
  3. if we are before the last line, branch to the created label $!ba ($! means not to do it on the last line (as there should be one final newline)).
  4. finally the substitution replaces every newline with a space on the pattern space (which is the whole file).
share|improve this answer
I cannot verify this is correct, but +1 for being able to understand it ;-) –  Arjan Aug 9 '09 at 20:33
Very cool. I found my first command that works in Ubuntu but not in Mac. –  Masi Aug 9 '09 at 21:01
@Arjan and Masi: OS X uses BSD's sed rather than GNU sed, so there may be some subtle (and some not so subtle) differences in the two. This is a constant pain if you work on both OS X and *nix machines. I usually install GNU's coreutils and findutils on OS X, and ignore the BSD versions. –  Telemachus Aug 9 '09 at 21:32
The :a isn't a register, it's a branch label. It's a target for the b command* which works like "goto". Calling it a register implies that you can create storage locations. There are only two "registers"; one is called the "hold space" which your script isn't using and the other is called the "pattern space". The N command appends a newline and and the next line of the input file to the pattern space. [*You can have multiple labels & b commands. If you have a b command without a label char appended to it, it branches to the end of the script to read the next line and loop again.] –  Dennis Williamson Oct 17 '09 at 17:52
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' –  Benjie Sep 27 '11 at 11:16
show 19 more comments

Use tr instead?

tr '\n' ' ' < input_filename
share|improve this answer
+1 for solving the problem with another tool –  Masi Aug 9 '09 at 19:20
Sed is line-based therefore it is hard for it to grasp newlines. –  Alexander Gladysh Aug 9 '09 at 19:22
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. –  dmckee Aug 9 '09 at 19:39
+1 For using the right tool for the job. –  poindexter Nov 2 '11 at 21:17
tr is great, but you can only replace newlines with single characters. You need to use a different tool if you want to replace newlines with a string –  Eddy Aug 1 '12 at 9:06
show 12 more comments

Fast answer:

  1. :a create a label 'a'
  2. N append the next line to the pattern space
  3. $! if not the last line, ba branch (go to) label 'a'
  4. s substitute, /\n/ regex for new line, / / by a space, /g global match (as many times as it can)

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


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

perl -p -e 's/\n/ /' file

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

tr '\n' ' ' < file

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

paste -s -d ' ' file

with awk, tr-like speed

awk 1 ORS=' ' file

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:


newline is always stripped off before the line is placed into the

terminating newline, puts what is left into the pattern space where
newline is not added in such cases. Thus, scripts like


will NEVER work, because the trailing newline is removed before
use one of these scripts instead:


delete all newlines.

to match lines between two specified addresses.

example can be modified by changing the delete command to something
or 's' (substitute).

even need the \n to find what you're looking for. Since GNU sed
version 3.02.80 now supports this syntax:



share|improve this answer
tr was a great idea, and your overall coverage makes for a top-quality answer. –  New Alexandria Jan 6 '13 at 17:57
awk does not need to read the whole file. It starts processing as soon as it has read a record, which by default is a line. –  Thor May 15 '13 at 7:02
@elgalu try this unix.stackexchange.com/questions/4527/… –  hdorio Dec 11 '13 at 9:36
The best part about this answer is that the "long answer" explains exactly how and why the command works. –  pdwalker May 2 at 11:20
show 9 more comments

A shorter awk alternative:

awk 1 ORS=' '


An awk program is built up of rules which consist of conditional code-blocks. If the code block is omitted the default ({ print $0 }) is used. Thus the 1 is interpreted as a true condition and print $0 is executed for each line.

When awk reads the input it splits it into records based on the value of RS (Record Separator), which by default is a newline, thus awk will by default parse the input linewise. The splitting also involves stripping off RS from the input record.

Now, when printing a record, ORS (Output Record Separator) is appended to it (default is again a newline). So by changing ORS to a space all newlines are changed to spaces.

share|improve this answer
looks cool, but this deletes the newlines, instead of replacing them with a space as per the question! –  cnst Mar 28 '13 at 14:59
@cnst: good point, I fixed it by changing ORS to a space. Thank you. –  Thor Apr 1 '13 at 0:10
clear, simple, elegant, and functioning! +1. –  Ed Morton Apr 2 '13 at 2:09
I like a lot this simple solution, which is much more readable, than others –  Fedir Jul 30 '13 at 13:29
@Melebius: see update. –  Thor Dec 4 '13 at 13:47
show 1 more comment

The perl version works the way you expected.

perl -i -p -e 's/\n//' file

Edit: As pointed out in the comments, it's worth noting that this edits in place. -i.bak will give you a backup of the original file before the replacement in case your regex isn't as smart as you thought.

share|improve this answer
Please at least mention that -i without a suffix makes no backup. -i.bak protects you from an easy, ugly mistake (say, forgetting to type -p and zeroing out the file). –  Telemachus Aug 9 '09 at 20:31
@Telemachus: It's a fair point, but it can be argued either way. The main reason I didn't mention it is that the sed example in the OP's question doesn't make backups, so it seems superfluous here. The other reason is that I've never actually used the backup functionality (I find automatic backups annoying, actually), so I always forget it's there. The third reason is it makes my command line four characters longer. For better or worse (probably worse), I'm a compulsive minimalist; I just prefer brevity. I realise you don't agree. I will try my best to remember to warn about backups in future. –  ire_and_curses Aug 9 '09 at 20:53
@Ire_and_curses: Actually, you just made a damn good argument for ignoring me. That is, you have reasons for your choices, and whether or not I agree with the choices, I certainly respect that. I'm not sure entirely why, but I've been on a tear about this particular thing lately (the -i flag in Perl without a suffix). I'm sure I'll find something else to obsess about soon enough. :) –  Telemachus Aug 9 '09 at 21:36
@ire_and_curses: I just checked, and I hadn't realized that I've bothered you in particular about this twice in the last two or three days. Time for me to let go of this particular issue and go for a walk, I think. –  Telemachus Aug 9 '09 at 21:39
show 1 more comment

In order to replace all newlines with spaces using awk, without reading the whole file into memory:

awk '{printf "%s ", $0}' inputfile

If you want a final newline:

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

You can use a character other than space:

awk '{printf "%s|", $0} END {printf "\n"}' inputfile
share|improve this answer
show 1 more comment

who needs sed. bash:

cat test.txt |  while read line; do echo -n "$line "; done
share|improve this answer
Upvote, I normally used the top answer, but when piping /dev/urandom through it, sed won't print until EOF, and ^C is no EOF. This solution prints every time it sees a newline. Exactly what I needed! Thanks! –  Vasiliy Sharapov Feb 9 '11 at 17:34
then why not: echo -n `cat days.txt` From this post –  Tony Sep 26 '12 at 23:51
@Tony because backticks are deprecated and the cat is redundant ;-) Use: echo $(<days.txt) –  seumasmac Feb 7 '13 at 16:03
Without even using cat: while read line; do echo -n "$line "; done < test.txt. Might be useful if a sub-shell is a problem. –  Carlo Cannas Jan 20 at 17:42
add comment

olldddd thread, but three things.

0.) tr (or cat, etc.) is absolutely not needed. (gnu) sed and (gnu) awk, when combined, can do 99.9% of any text processing you need.

1.) stream != line based. ed is a line-based editor. sed is not. See sed lecture for more information on the difference. Most people confuse sed to be line-based because it is, by default, not very greedy in its pattern matching for SIMPLE matches- for instance, when doing pattern searching and replacing by one or two characters, it by default only replaces on the first match it finds (unless specified otherwise by the global command). there would not even be a global command if it were line-based rather than STREAM-based, because it would evaluate only lines at a time. try running ed, you'll notice the difference. ed is pretty useful if you want to iterate over specific lines (such as in a for-loop), but most of the times you'll just want sed.

2.) That being said,

sed -e '{:q;N;s/\n/ /g;t q}' file

works just fine in GNU sed version 4.2.1. The above command will replace all newlines with spaces. It's ugly and a bit cumbersome to type in, but it works just fine. The {}'s can be left out, as they're only included for sanity reasons.

share|improve this answer
What is one? I do not know this command! –  brandizzi Aug 3 '11 at 0:48
show 1 more comment

I'm not an expert, but I guess in sed you'd first need to append the next line into the pattern space, bij using "N". From the section "Multiline Pattern Space" in "Advanced sed Commands" of the book sed & awk (Dale Dougherty and Arnold Robbins; O'Reilly 1997; page 107 in the preview):

The multiline Next (N) command creates a multiline pattern space by reading a new line of input and appending it to the contents of the pattern space. The original contents of pattern space and the new input line are separated by a newline. The embedded newline character can be matched in patterns by the escape sequence "\n". In a multiline pattern space, the metacharacter "^" matches the very first character of the pattern space, and not the character(s) following any embedded newline(s). Similarly, "$" matches only the final newline in the pattern space, and not any embedded newline(s). After the Next command is executed, control is then passed to subsequent commands in the script.

From man sed:


Append the next line of input to the pattern space, using an embedded newline character to separate the appended material from the original contents. Note that the current line number changes.


share|improve this answer
show 3 more comments

The answer with the :a register ...

SED: How can I replace a newline (\n)?

... does not work in freebsd 7.2 on the command line:

( echo foo ; echo bar ) | sed ':a;N;$!ba;s/\n/ /g'
sed: 1: ":a;N;$!ba;s/\n/ /g": unused label 'a;N;$!ba;s/\n/ /g'

But does if you put the sed script in a file or use -e to "build" the sed script...

> (echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g'
foo bar

or ...

> cat > x.sed << eof
s/\n/ /g

> (echo foo; echo bar) | sed -f x.sed
foo bar

Maybe the sed in OS X is similar.

share|improve this answer
show 1 more comment

In response to the "tr" solution above, on Windows (probably using the Gnuwin32 version of tr), the proposed solution:

tr '\n' ' ' < input

was not working for me, it'd either error or actually replace the \n w/ '' for some reason.

Using another feature of tr, the "delete" option -d did work though:

tr -d '\n' < input

or '\r\n' instead of '\n'

share|improve this answer
On Windows, you probably need to use tr "\n" " " < input. The Windows shell (cmd.exe) doesn't treat the apostrophe as a quoting character. –  Keith Thompson Aug 24 '11 at 14:25
add comment

Easy-to-understand Solution

I had this problem. The kicker was that I needed the solution to work on BSD (osx) and GNU (linux, cygwin) sed and tr.

$ echo 'foo

baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'



(has trailing newline)

Works on Linux, OS X, and BSD - even without UTF8 support or with a crappy terminal.

  1. Use tr to swap the newline with another character.

    NULL (\000 or \x00) is nice because it doesn't need utf-8 support and it's not likely to be used

  2. Use sed to match the NULL

  3. Use tr to swap back extra newlines if you need them

share|improve this answer
add comment
tr '\n' ' ' 

is the command.

Simple and easy to use.

share|improve this answer
add comment

@OP, if you want to replace newlines in a file, you can just use dos2unix (or unix2dox)

dos2unix yourfile yourfile
share|improve this answer
add comment

Using Awk:

awk "BEGIN { o=\"\" }  { o=o \" \" \$0 }  END { print o; }"
share|improve this answer
You don't need to escape the quotation marks and dollar sign if you change the outer ones to single quotes. The letter "o" is usually considered a bad choice as a variable name since it can be confused with the digit "0". You also don't need to initialize your variable, it defaults to a null string. However, if you don't want an extraneous leading space: awk '{s = s sp $0; sp = " "} END {print s}'. However, see my answer for a way to use awk without reading the whole file into memory. –  Dennis Williamson Mar 30 '12 at 6:34
show 2 more comments

In some situation maybe you can change the RS to some other string or char, this way \n is available for sub/gsub

cat file | gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }'

The power of shell scripting is that if you do not know how to do it in one way you can do it in another way. And many times you have more things to take into account than make a complex solution on a simple problem. Regarding the thing that gawk is slow... and reads the file into memory, I do not know this but to me gawk seems to work with one line at the time and is very very fast (not that fast as some of the others but the time to write and test also counts) . I process MB and even GB of data and the only limit I found is line size.

share|improve this answer
Useless use of cat. –  Dennis Williamson Mar 30 '12 at 6:35
add comment

I used a hybrid approach to get around the newline thing by using tr to replace newlines with tabs, then replacing tabs with whatever I want. In this case "
" since I'm trying to generate html breaks.

echo -e "a\nb\nc\n" |tr '\n' '\t' | sed 's/\t/ <br> /g'`
share|improve this answer
add comment

Replace newlines with any string, and replace the last newline too

The pure tr solutions can only replace with a single character, and the pure sed solutions don't replace the last newline of the input. The following solution fixes these problems, and seems to be safe for binary data (even with a UTF-8 locale):

printf '1\n2\n3\n' |
  sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'


share|improve this answer
show 3 more comments

You could use xargs — it will replace \n with a space by default.

However, it would have problems if your input has any case of an unterminated quote, e.g. if the quote signs on a given line don't match.

share|improve this answer
add comment

On Mac OS X (using FreeBSD sed):

# replace each newline with a space
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g; ta'
share|improve this answer
add comment

A solution I particularly like is to append all the file in the hold space and replace all newlines at the end of file:

$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'

However, someone said me the hold space can be finite in some sed implementations.

share|improve this answer
add comment

To remove empty lines:

sed -n "s/^$//;t;p;"
share|improve this answer
add comment

It is sed that introduces the new-lines after "normal" substitution. First, it trims the new-line char, then it processes according to your instructions, then it introduces a new-line.

Using sed you can replace "the end" of a line (not the new-line char) after being trimmed, with a string of your choice, for each input line; but, sed will output different lines. For example, suppose you wanted to replace the "end of line" with "===" (more general than a replacing with a single space):

PROMPT~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line

first line===
second line===
3rd line===

To replace the new-line char with the string, you can, inefficiently though, use tr , as pointed before, to replace the newline-chars with a "special char" and then use sed to replace that special char with the string you want.

For example:

PROMPT~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line

first line===second line===3rd line===PROMPT~$
share|improve this answer
add comment

Bullet-proof solution. Binary-data-safe and POSIX-compliant, but slow.

POSIX sed requires input according to the POSIX text file and POSIX line definitions, so NULL-bytes and too long lines are not allowed and each line must end with a newline (including the last line). This makes it hard to use sed for processing arbitrary input data.

The following solution avoids sed and instead converts the input bytes to octal codes and then to bytes again, but intercepts octal code 012 (newline) and outputs the replacement string in place of it. As far as I can tell the solution is POSIX-compliant, so it should work on a wide variety of platforms.

od -A n -t o1 -v | tr ' \t' '\n\n' | grep . |
  while read x; do [ "0$x" -eq 012 ] && printf '<br>\n' || printf "\\$x"; done

POSIX reference documentation: sh, shell command language, od, tr, grep, read, [, printf.

Both read, [, and printf are built-ins in at least bash, but that is probably not guaranteed by POSIX, so on some platforms it could be that each input byte will start one or more new processes, which will slow things down. Even in bash this solution only reaches about 50 kB/s, so it's not suited for large files.

Tested on Ubuntu (bash, dash, and busybox), FreeBSD, and OpenBSD.

share|improve this answer
add comment

Sed without buffers (good for real time output)
Example: replacing newline by <br/> break in HTML

echo -e "1\n2\n3" | sed 's/.*$/&<br\/>/'
share|improve this answer
add comment

This is really simple .. I really gt irritated when i found the solution .. There was just one more back slash missing .. This is it..

sed -i "s/\\\\\n//g" filename
share|improve this answer
Doesn't work here. –  artur Sep 29 '11 at 20:01
add comment

this is a lot simpler than most answers, also it is working:

echo `sed -e 's/$/\ |\ /g' file`

share|improve this answer
This isn't working, since it doesn't replace the newline, but prepend some text to each line. –  leemes Jun 14 '12 at 1:48
add comment
sed -n "H;$ {x;s/\n/ /g;p;}" file

Does not work for huge file (buffer limit) but very efficient if enough memory to hold the file.

share|improve this answer
add comment

You can use xargs

seq 10 | xargs


seq 10 | xargs echo -n
share|improve this answer
add comment

Try this:

echo "a,b"|sed 's/,/\r\n/'
share|improve this answer
add comment

protected by H2CO3 Sep 17 '12 at 16:01


Would you like to answer one of these unanswered questions instead?
