pyenv安装说明中的高级sed命令

pyenv安装说明中的高级sed命令

皮恩夫存储库,具有以下用于 bash 的 sed 命令:

sed -Ei -e '/^([^#]|$)/ {a \
export PYENV_ROOT="$HOME/.pyenv"
a \
export PATH="$PYENV_ROOT/bin:$PATH"
a \
' -e ':a' -e '$!{n;ba};}' ~/.profile

这是如何运作的?

答案1

您显示的命令将两行文本添加到您的~/.profile文件中。这些线是

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

它们通过命令添加a(GNU命令每行sed使用一次,这是不必要的)。一旦正则表达式匹配,命令就会被a执行。正则表达式将匹配第一行不以a^([^#]|$)#或为空的第一行。行已附加那条触发线。

结尾是一个显式循环,它仅允许通过读取下一行、打印它并继续直到文件末尾来保持文档的其余部分保持不变。这可以避免在与正则表达式匹配并触发两个命令的每一行之后添加两行文本a

该命令写得相当笨拙,因为需要进行一些分析才能弄清楚它应该做什么。其要点是,它尝试~/.profile尽早在文件中任何初始注释块之后的第一行之后插入新内容。它可能应该使用i而不是a在注释之后添加行,而不是在注释之后的第一行之后添加行。

就我个人而言,我只会在结尾脚本的:

cat >>"$HOME/.profile" <<'PYENV_SETUP_ENDS'
export PYENV_ROOT="$HOME/.pyenv"
PATH=$PYENV_ROOT/bin:$PATH
PYENV_SETUP_ENDS

(注意PATH不需要再次导出。)


使用最新的 GNU awk,您可以sed使用以下命令复制该命令

awk -i inplace '
    { print }
    !a && (/^[^#]/ || length == 0) {
        print "export PYENV_ROOT=\"$HOME/.pyenv\""
        print "PATH=$PYENV_ROOT/bin:$PATH"
        a = 1
    }' ~/.profile

交换代码中的两个块awk以获取在初始注释块之后添加的行,而不是在初始注释块之后的第一行之后添加的行。


相同的 GNUsed命令,但进行了一些清理并使用了更多的空气进行演示:

sed -i -f - ~/.profile <<'END_SED'
/^#/ b

a \
export PYENV_ROOT="$HOME/.pyenv"\
PATH=$PYENV_ROOT/bin:$PATH

:again
$ ! {
    n
    b again
}
END_SED

将命令更改ai直接插入到第一个非注释行之后。

相关内容