sed 's/ /\ /g' の仕組み

sed 's/ /\ /g' の仕組み

Composerが追加したパッケージで、次のスクリプト行が見つかりました。

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

Git Bashで試してみました。

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

これがどのように機能するかを説明できますか?二重バックスラッシュと一致するものはありません。

編集する。

今私の間違いが見えます。 echoで二重バックスラッシュを単一のバックスラッシュに変えることはsedとは何の関係もありません。

odGit Bashにはありませんが、試してみました。

$ 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

。 1文字以上out.txt短いですin.txt

sed 's/ /\ /g'しかし、私はまだそれが実際に何をしているのか、なぜするのか理解していません。

文脈全体が観客にとって役に立ちますか?

#!/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" "$@"

答え1

これはsed関係ありません。あなたが見ることは実際にechoそれ自体で行われます。

$ echo "foo\bar\ foo/baz/ qux\\bax\\ " 
foo\bar\ foo/baz/ qux\bax\ 

\他の文字をエスケープするために使用されるからです。\\「エスケープ」を意味するので、1つだけ\印刷されます。sed入力スペースのエスケープなどの便利な作業を実行するには、次のものが必要です。

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

答え2

sedは二重バックスラッシュを見ることができないかもしれませんし、エコーを通して一つにマージされます。説明にはいくつかのレベルがあります。ここではシェルは重要ではありませんが、echoのバージョンによってはechoが重要です。したがって、printfを使用する方が良いですが、printfは最初の引数も解釈することに注意してください。さまざまな状況でsedに入力されているものを見てください。

$ 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

4番目のものだけが二重バックスラッシュを送信します。このバックスラッシュは最初にechoによって削除され、次にprintfによって削除され、3番目はシェルによって削除されます。

関連情報