使用 Sed 或 Perl 替换 .bashrc 中的 PS1 变量

Replacement of PS1 variable in .bashrc using Sed or Perl

我正在尝试替换文件中的一行,但 运行 遇到了问题。

原文件:

export PS1='\h:\w$ '

命令我是运行:

perl -pi -e 's~PS1.*~PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]~g' ~/.bashrc

错误信息:

syntax error at -e line 1, near "e["
Execution of -e aborted due to compilation errors.

我也试过sed:

sed -i 's~PS1.*~PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]~g' ~/.bashrc

使用 Sed 的结果:

export PS1="
[e[32;1m][[e[37;1m]@h:[e[37;1m]w[e[32;1m]]$ [e[0m]

预期结果文件:

export PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"

最终结果

这与问题没有太大关系,只是向人们展示 PS1 在正常工作时的样子

对于 sed,您必须使用另一个反斜杠对每个反斜杠进行转义,以便按字面意思对待它们。

s命令还需要转义分隔符和&,所以使用c命令更容易,所以双反斜杠是唯一的要求:

sed -i '/PS1/c\
export PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\\$ \[\e[0m\]"
' file.txt

如果file.txt包含:

hello
PS1=foo
world

然后在运行这个命令之后,它将包含:

hello
export PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"
world

只需使用可以处理文字字符串的工具,例如awk:

$ awk 'BEGIN{new=ARGV[1]; ARGV[1]=""} sub(/PS1=.*/,"PS1="){[=10=]=[=10=] new} 1' \
    '"\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"' file
export PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"

或者如果您愿意:

$ new='"\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"' \
    awk 'sub(/PS1=.*/,"PS1="){[=11=]=[=11=] ENVIRON["new"]} 1' file
export PS1="\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"

sed 没有任何机制来理解文字字符串,请参阅 以了解您需要跳过哪些环节才能让 sed 像它那样工作。

您可以使用纯 Bash 代码执行此操作:

newps1='"\n\[\e[32;1m\][\[\e[37;1m\]\u@\h:\[\e[37;1m\]\w\[\e[32;1m\]]\$ \[\e[0m\]"'
readarray -t bashrc_lines <~/.bashrc
printf '%s\n' "${bashrc_lines[@]/PS1=*/PS1=$newps1}" >~/.bashrc

唯一需要的引号是用单引号将要放在 PS1=.

右侧的确切字符串(包括双引号)括起来

代码需要 Bash 4(或 5)个 readarray。它会将所有“.bashrc”文件读入内存,但这在实践中应该不是问题。 (如果它太大而无法加载到内存中,那么几乎可以肯定它太大而不能成为有用的“.bashrc”。)

有关如何进行替换的信息,请参阅 Substituting part of a string (BashFAQ/100 (How do I do string manipulation in bash?))