Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I replace spaces with new lines on an input like:

/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5 etc...

To obtain the following:



I'm posting this question to help other users, it was not easy to find a useful answer on UNIX SE until I started to type this question. After that I found the following:

Related question

How can I find and replace with a new line?

share|improve this question

6 Answers 6

up vote 1 down vote accepted

Assuming you have a string with spaces as separators:

newline_separated=${space_separated// /$'\n'}

However you're probably asking the wrong question. (Not necessarily, for example this might come up in a makefile.) A space-separated list of file names doesn't really work: what if one of the file names contained spaces?

If a program receives file names as arguments, don't join them with spaces. Use "$@" to access them one by one. Although echo "$@" prints the arguments with spaces in between, that's due to echo: it prints its arguments with spaces as separators. somecommand "$@" passes the file names as separate arguments to the command. If you want to print the arguments on separate lines, you can use

printf '%s\n' "$@"

If you do have space-separated file names and you want to put them in an array to work on them, you can use an unquoted variable expansion to split the value at characters on IFS (you'll need to disable wildcard expansion with set -f, otherwise glob patterns will be expanded in the value):

space_separated_list='/path/to/file1 /path/to/file2 /path/to/file3'
IFS=' '; set -f
eval "array=(\$space_separated_list)"
for x in "${array[@]}"; do …

You can encapsulate this in a function that restores the -f setting and the value of IFS when it's done:

split_list () {
  local IFS=' ' flags='+f'
  if [[ $- = *f* ]]; then flags=; fi
  set -f
  eval "$1=($2)"
  set $flags
split_list array '/path/to/file1 /path/to/file2 /path/to/file3'
for x in "${array[@]}"; do …
share|improve this answer
Changing the correct answer to this one. I think it's more correct to research how I got to a space-separated list, and retrieve that information in another way. It would be cool for learners like me if you comment a bit your snipnet, telling us what do things like the local var IFS or the condition $- = f do. That kind of things a person that uses bash few times don't knows. –  laconbass Dec 11 at 22:01
@laconbass I've added a short explanation. Look up set -f and IFS in the bash manual if you want all the details. See also unix.stackexchange.com/questions/16192/… –  Gilles Dec 11 at 22:26
@Guilles That short explanation is enough for me, and i think it will be for many others. Ty for your time –  laconbass Dec 12 at 2:31

Use the tr command

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"

Found on http://www.unix.com/shell-programming-scripting/67831-replace-space-new-line.html

share|improve this answer
tr was my first thought as well, although there are so many ways to do it! This is pretty much EXACTLY what tr is for, though! –  Rob Dec 17 '13 at 15:43
+1, but as a comment: That does not work if the filenames contain spaces themselves –  Bonsi Scott Dec 17 '13 at 16:10

In this case I would use printf:

printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5

If there are spaces within the one of the paths, you can quote that filepath in order to prevent it from being split on the spaces:

printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file

To transform text in general, tr is your best bet, as covered in an existing answer.

share|improve this answer

Here is how I did it:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5" | sed 's/ /\

Notice the use of Enter key after backslash in the sed command.

share|improve this answer
what prons and cons has sed over tr? –  laconbass Dec 17 '13 at 15:33
Your comfort level :-) I think you can do more with sed as it is an editor rather than simply translate characters. –  unxnut Dec 17 '13 at 15:38
sed can do so much more, but is totally overkill for this. tr is the right tool for THIS job, but knowledge of sed and regexes will certainly come in handy later! –  Rob Dec 17 '13 at 15:44
@Rob thanks for the tip –  laconbass Dec 17 '13 at 16:33

Another approach, assuming the line is in a variable called line:

for path in $line;do echo $path;done

This makes use of the fact that Bash splits its arguments on whitespace by default and that echo appends a newline to its input by default.

share|improve this answer
I tried this on my ubuntu system before i posted this question and couldn't get it to work. –  laconbass Dec 17 '13 at 16:38

Be pragmatic, use sed!!

sed 's/\s+/\n/g' file

This is more or less:

'substitute /one space or more/ for /newline/ globally'
share|improve this answer
replace change with substitute, that's what the s actually stands for! –  Rob Dec 17 '13 at 16:37
@Rob thanks, remember you can edit others answers. –  Manuel Gutierrez Dec 17 '13 at 16:42
If you have multiple spaces between text then you will get blank lines. You need to add a '+' after the \s to indicate that you want to match at least one spaces as apposed to exactly one space. ie. sed 's/\s+/\n/g' –  DarkHeart Dec 17 '13 at 20:43
@DarkHeart fixed, thanks. –  Manuel Gutierrez Dec 17 '13 at 21:58

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.