# How works sed 's/ /\ /g'

I found this line script in package added by Composer

dir=$(echo$dir | sed 's/ /\ /g')


I tried in the Git Bash

$echo$(echo "foo\bar\ foo/baz/ qux\\bax\\ " | sed 's/ /\ /g')
foo\bar\ foo/baz/ qux\bax\


Can you explain how this works? I can't see match for double backslash.

EDIT.

Now I see my mistake. Turning double backslash to one backslash in echo has nothing to do with sed.

I don't have od in the Git Bash, but I tried.

$echo "foo\bar\ foo/baz/ qux\\bax\\ " >in.txt$ echo $(echo "foo\bar\ foo/baz/ qux\\bax\\ " | sed 's/ /\ /g') >out.txt$ cmp -l in.txt out.txt
27  40  12
cmp: EOF on out.txt


The out.txt is one character shorter than in.txt.

But I still don't get what does sed 's/ /\ /g' actually do and why.

Might the entire context be useful for viewers

#!/usr/bin/env sh

dir=$(d=${0%[/\\]*}; cd "$d"; cd "../squizlabs/php_codesniffer/scripts" && pwd) # See if we are running in Cygwin by checking for cygpath program if command -v 'cygpath' >/dev/null 2>&1; then # Cygwin paths start with /cygdrive/ which will break windows PHP, # so we need to translate the dir path to windows format. However # we could be using cygwin PHP which does not require this, so we # test if the path to PHP starts with /cygdrive/ rather than /usr/bin if [[$(which php) == /cygdrive/* ]]; then
dir=$(cygpath -m$dir);
fi
fi

dir=$(echo$dir | sed 's/ /\ /g')
"${dir}/phpcs" "$@"

• The sed command you provided has no effect (it replaces a space with a space). Are you sure that's what the script says? If so, it's probably a mistake intending to precede every space with a backslash. – Michael Homer Dec 7 '15 at 8:28
• (Strictly, I think it has undefined behaviour, but I don't know of an implementation that behaves the way that seems to be intending.) – Michael Homer Dec 7 '15 at 8:28
• I have voted to accept your edit even though it's from user "Tygr Lew". Please either merge the two accounts or ensure that you're editing with the same user id that you used to ask the question. Properly, I should have rejected the edit because I have no evidence that user146341 and Tygr Lew are the same person. – roaima Dec 7 '15 at 23:04

The sed is irrelevant. What you see is actually done by the echo itself:

$echo "foo\bar\ foo/baz/ qux\\bax\\ " foo\bar\ foo/baz/ qux\bax\  This is because \ is used to escape other characters. The \\ is taken to mean "escape the \" so only one is printed. If you wanted to make the sed do something useful like escaping the spaces of the input, you would need: $ echo "foo\bar\ foo/baz/ qux\\bax\\ " | sed 's/ /\\ /g'
foo\bar\\ foo/baz/\ qux\bax\\


sed probably does not even see the double backslashes, they are merged into one by echo. There are several levels of interpretation. The shell should not matter here but depending on the version of echo, echo does matter. So better use printf, but pay attention to the fact that printf also interpret its first argument. So look at what is fed into sed in various cases:

$echo "foo\bar\ foo/baz/ qux\\bax\\ " | od -t c 0000000 f o o \b a r \ f o o / b a z / 0000020 q u x \ b a x \ \n 0000033$ printf "foo\bar\ foo/baz/ qux\\bax\\ " | od -t c
0000000   f   o   o  \b   a   r   \       f   o   o   /   b   a   z   /
0000020       q   u   x   \   b   a   x   \
0000032
$printf '%s\n' foo\bar\ foo/baz/\ qux\\bax\\ | od -t c 0000000 f o o b a r f o o / b a z / 0000020 q u x \ b a x \ \n 0000031$ printf '%s\n' "foo\bar\ foo/baz/ qux\\bax\\ " | od -t c
0000000   f   o   o   \   b   a   r   \       f   o   o   /   b   a   z
0000020   /       q   u   x   \   \   b   a   x   \   \      \n
0000036


Only the fourth one has double backslashes transmitted, they are removed first by echo, then by printf and third by the shell.

• True, but I don't see how this answers the question. Are you going to apply this to the question as asked, to show the the sed does nothing in three different ways? – roaima Dec 7 '15 at 8:46