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

时间:2019-02-08 20:48:52

标签: linux bash perl sed ps1

我正在尝试替换文件中的一行并遇到问题。

原始文件:

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的外观之外,这与问题没有太大关系

enter image description here

3 个答案:

答案 0 :(得分:1)

对于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

答案 1 :(得分:0)

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

$ awk 'BEGIN{new=ARGV[1]; ARGV[1]=""} sub(/PS1=.*/,"PS1="){$0=$0 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="){$0=$0 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没有任何机制来理解文字字符串,请参阅Is it possible to escape regex metacharacters reliably with sed,以获得需要让sed发挥作用的跳环。

答案 2 :(得分:0)

您可以使用纯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=右边的确切字符串(包括双引号)周围加上单引号。

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

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