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:

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

Note

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 11 down vote accepted

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
2  
+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/ /\
'/g

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
4  
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

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:

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

Your Answer

 
discard

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.