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 无关。

od我在 Git 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

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\ 

这是因为\用于转义其他字符。 The 的\\意思是“转义\”,因此只打印一个。如果你想让它sed做一些有用的事情,比如转义输入的空格,你需要:

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

答案2

sed 可能甚至看不到双反斜杠,它们通过 echo 合并为一个。有几个层次的解释。 shell 在这里应该不重要,但根据 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

只有第四个传输了双反斜杠,它们首先被 echo 删除,然后被 printf 删除,第三次被 shell 删除。

相关内容