57

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

90

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
    – Peter.O
    Dec 14, 2011 at 6:17
  • @ferer Thanks for the information. Installing moreutils...
    – pferor
    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' ' ' Feb 2 at 8:44
13

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" Feb 2 at 8:47
9

You could try using tr instead:

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

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
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.
    – Peter.O
    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
    – Adrian
    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.

Not the answer you're looking for? Browse other questions tagged .