我正在尝试替换文件中的一行并遇到问题。
原始文件:
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的外观之外,这与问题没有太大关系
答案 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?))。