皮恩夫存储库,具有以下用于 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
将命令更改a
为i
直接插入到第一个非注释行之后。