为什么 sed 无法看到我的 PS1 提示?

Why would sed have trouble seeing my PS1 prompt?

我正在尝试将 sed 用作 root 来更改默认值 PS1

前两行只是为了确保我的语法结构正确并查看引号是否有所不同, 运行 它们连续允许我更改文件顶部附近的注释,然后再将其更改回来。 在 nano 中打开文件确认更改有效,这应该排除 'write permissions'.

sed -i 's/If not running interactively,/stringtoreplaceitwith/' /etc/skel/.bashrc
sed -i "s/stringtoreplaceitwith/If not running interactively,/" /etc/skel/.bashrc
sed -i "s/\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$ /Replace PS1/" /etc/skel/.bashrc

我不确定它是否与字符串的结构有关, 但出于某种原因,它没有找到我想要替代的东西。

\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$ 

(尾随空格)。

你的问题是引用和转义引起的。让我们将您要替换的字符串缩减为:

\w\[3[00m\]$

(尾随空白)- 这包含所有困难,但不那么冗长。

要匹配这个,我们必须

  • 转义所有反斜杠:\w 变为 \w
  • 转义 [],因为它们对 sed 是特殊的:[ 变成 \[,而 \[ 变成 \\[ (转义反斜杠,转义 [
  • 转义$$变成\$

然后,我们必须在我们的 sed 命令周围使用 单引号 ,这样 shell 就不会修改字符串:

$ sed 's/\w\\[\033\[00m\\]\$ /Replace PS1/' <<< '\w\[3[00m\]$ '
Replace PS1

它也可以使用双引号,但是我们必须为 shell 添加 另一轮 转义: \[ 变为 \\[(为 sed 转义)变为 \\\[(为 shell 转义),依此类推。

$ sed "s/\\w\\\[\\033\[00m\\\]\\\$ /Replace PS1/" <<< '\w\[3[00m\]$ '
Replace PS1

不过,出于显而易见的原因,双引号只有在您使用变量时才有意义。

最后,对于您的实际字符串:

$ echo '\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$ ' \
    | sed 's/\\[\033\[01;32m\\]\u@\h\\[\033\[00m\\]:\\[\033\[01;34m\\]\w\\[\033\[00m\\]\$ /Replace PS1/'
Replace PS1