62

Say I have a shell variable $string that holds some text with several newlines, e.g.:

string="this
is 
a test"

I would like to convert this string into a new string new_string where all line breaks are converted into spaces:

new_string="this is a test"

I tried:

print $string | sed 's/\n/ /g'

but it didn't work

I'm also wondering if there is a way of doing this using perl -0777 's/\n/ /g' or maybe the command tr ?

3

9 Answers 9

101

If you only want to remove the new lines in the string, you don't need to use sed. You can use just

$  echo "$string" | tr '\n' ' '

as others had pointed.

But if you want to convert new lines into spaces on a file using sed, then you can use:

# for a file
$ sed -i ':a;N;$!ba;s/\n/ /g' file_with_line_breaks

# for a string
$ new_string="$(echo "$string" | sed ':a;N;$!ba;s/\n/ /g')"

or even awk:

$ awk '$1=$1' ORS=' ' file_with_line_breaks > new_file_with_spaces
3
  • 2
    sponge is a useful utility for overwriting an input file. It is part of package moreutils ... eg. awk '$1=$1' ORS=' ' file |sponge file Commented Dec 14, 2011 at 6:17
  • @ferer Thanks for the information. Installing moreutils... Commented Dec 14, 2011 at 13:25
  • Your first command will add a space at the end. Also it may fail if the $string starts with a dash -. To avoid both the problems you should use printf: printf %s "$string" | tr '\n' ' ' Commented Feb 2, 2023 at 8:44
15

Yet another option would be to use xargs (which, in addition, squeezes multiple white space):

string="this
    is 
a    test"

printf "$string" | xargs   # this is a test
1
  • Do not use the string as the formatting argument of printf. This will fail if it contains the formatting characters like % or \. Do this instead: printf %s "$string" Commented Feb 2, 2023 at 8:47
11

If you already have the string as a bash variable, as your example shows, it is pointless and wasteful of resources (and more typing) to call sed, awk, printf, etc... You can just use bash variable expansion:

string="${string//$'\n'/ }"

You don't even have to re-assign it. You can use the expansion as-is, and leave $string unchanged.

printf "${string//$'\n'/ }" >file
10

You could try using tr instead:

echo "$string" | tr '\n' ' '
5

You could try this awk command also,

awk -v RS="" '{gsub (/\n/," ")}1' file

Example:

$ (echo This; echo is; echo a; echo test.) | awk -v RS="" '{gsub (/\n/," ")}1'
This is a test.
3

Echo ignores white space, so it should work:

new_string=`echo $string`
1
  • Yes, it will work, but perhaps too well. It will collapse multi whitespace to a single space. That includes converting TABs to spaces. Commented Dec 14, 2011 at 6:10
2

You can use the simple sed command

 $-sed ':loop;N;s/\n/ /g;t loop'
1
  • With in-place editing: sed -i ':loop;N;s/\n/ /g;t loop' file.txt Commented Sep 20, 2022 at 17:24
1
state=$(set +o)
set -f ; IFS='
'; set -- $string
unset IFS; string="$*"
eval "$state"

This converts any sequence of one or more \newline characters occurring in the shell variable $stringinto a single <space>.

1

I know the question is old, but you don't to use sed for this. If you really need to use sed, just look at the above answers.

Like @user57553's answer, you could use xargs. I personally would do xargs echo for more POSIX compliance (if it even is).

You can just do:

COMMAND | xargs echo

where COMMAND is well, the command.

If it's a file, do:

xargs echo < FILE

where FILE is the file you are trying to convert.

To do it backwards (spaces to newlines), do:

COMMAND | tr " " "\n"

If it's a file, do:

tr " " "\n" < FILE

where FILE is the file you are trying to convert.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.