使用 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?))。
我正在尝试替换文件中的一行,但 运行 遇到了问题。
原文件:
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 没有任何机制来理解文字字符串,请参阅
您可以使用纯 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?))。