前:

前:

我想改变PS1在我的程序中,~/.bashrc可以使用任何最流行的正则表达式工具 {sed或}。但是,我遇到了问题awkperl特殊字符。请注意,默认情况下,在不同条件下设置~/.bashrc了三个PS1提示变量,并且它们都是不同的。我只想更改其中两个,方法是注释掉原始PS1行并在其下修改原来的内容。

.bashrc为了说明起见,让我向您展示修改变量之前和之后的部分PS1。 (顺便说一句,为了增加可读性,我使用了自定义的连接标记“join”(\\j\)和“space”(\\s\)),前者表示两个部分连接在一起而它们之间没有任何空格字符,但后者允许两者之间有空格。

前:

如果 [ “$color_prompt” = 是 ]; 那么
  PS1='${debian_chroot:+($debian_chroot)} \\j\
    \[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
别的
  PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\n\$> '
  取消设置 color_prompt force_color_prompt

  # 如果这是一个 xterm,则将标题设置为 user@host:dir
  案例“$TERM”
  xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h:\w\a\]$PS1"
  ;;
  *)
  ;;
  埃萨克

后:

如果 [ “$color_prompt” = 是 ]; 那么
# PS1='${debian_chroot:+($debian_chroot)} \\j\
    \[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    PS1='${debian_chroot:+($debian_chroot)} \\j\
    \[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$> '
  别的
# PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\n\$> '
  取消设置 color_prompt force_color_prompt

  # 如果这是一个 xterm,则将标题设置为 user@host:dir
  案例“$TERM”
  xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h:\w\a\]$PS1"
  ;;
  *)
  ;;
  埃萨克

我得到了以下工作:

对于那些想要尝试的人,让我向你们展示我所得到的结果,同时我还了解到了 sed 的问题所在,以及 awk 和 perl 更胜一筹的地方,尽管在玩了一天 awk 和 perl 之后,我实际上只让 sed 完成了我想要做的事情的不到一半!

特别要注意连接技巧,将单引号字符串内的单引号替换为 {{ ' " ' " ' }} :即:

                           内部 内部
                         单引号 单引号
                             快来抢购
  aString=' 这是不带引号的 '"'"' 这是带单引号的 '"'"' '
  回显“[$aString]”
  [ 这是未加引号的 ' 这是加单引号的 ' ]

内部单引号实际上是两个单引号和一个恰好是双引号单引号 {{ ' " ' " ' }} 的字符串。当将它们放在一起时$aString,该字符串由五个连接的字符串组成:

    ' 这是不带引号的 ' + "'" + ' 这是带单引号的 ' + "'" + ' '

在 {{ }} 中你会踩到的另一个地雷sed是,{{ sed}} 由于某种原因不能处理 <Esc> 字符的八进制表示(\033) 正确,显然十六进制也可以,即 {{\x1b}} 或者 {{\x1B}},但文件中却不是这样 .bashrc,因为四个字符 {{\033}} 按照 ASCII {{\,0,33}} 但我相信 shell(Bash、Bourne 或 Perl)应该将这些出现的情况转换为它们所代表的适当的单个字符:在本例中为 <Esc> 字符。在我看来,这就像一团乱麻!我花了整个周末用 {{ sed, awk & perl }} 测试了转义、双重转义、八进制和十六进制组合的不同排列,我唯一能正常工作的是 {{ sed }} 中没有颜色代码的以下内容。在混合中添加颜色代码,只会毁掉我所知道的一切和我尝试的一切。

该 sed 代码有效:

二十九
 30 ps1_2=' PS1='"'"'${debian_chroot:+($debian_chroot)}\\u\@\\h:\\w\\$'"'"''
 31 ps1_2n=' PS1='"'"'${debian_chroot:+($debian_chroot)}\\u\@\\h:\\w\\n\\$> '"'"''
 三十二
 33 sed "s/$ps1_2/#&\n$ps1_2n/" ps1-tFILE.txt

解决了

斯科特,非常感谢您的及时回复,这给了我正确的方向。我通过先处理较小的部分然后将它们全部合并在一起来解决了我的问题。以下是我的做法:

  1 #!/usr/bin/env bash
  2 # $对数$
  3
  4 #--以下是{{ ps1-tFILE.txt }}文件的内容:
  5
  6 #^ PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\] \\j\
                \u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
  8 #^ 其他
  9 #^ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\n\$> '
 10
 11 P1=' PS1='"'"'${debian_chroot:+($debian_chroot)}'
 12 P2='\\\[\\033\[01;32m\\]'
 13 P3='\\u@\\h'
 14 P4='\\\[\\033\[00m\\]:'
 15 P5='\\\[\\033\[01;34m\\]\\w'
 16 P6='\\\[\\033\[00m\\]'
 17 P7='\\$'“'”''
 18
 19 srchPatt_wCtrls="\($P1$P2$P3$P4$P5$P6\)\($P7\)"
 20 replPatt_wCtrls='#&\n\1\\n\\$> '"'"'
 21
 22 # -- 为了方便起见,我还打印出了所有单独的部分 \\s\
            匹配和替换模式。
 23 回显“P1=$P1”
 24 回显“P2=$P2”
 25 回显“P3=$P3”
 26 回显“P4=$P4”
 27 回显“P5=$P5”
 28 回显“P6=$P6”
 29 回显“P7=$P7”
 30 回显“srchPatt_wCtrls=$srchPatt_wCtrls”
 31 回显“replPatt_wCtrls=$replPatt_wCtrls”
 三十二
 33 ps1_o=' PS1='"'"'${debian_chroot:+($debian_chroot)}\\u\@ \\j\
                    \\h:\\w\\$'“'”''
 34 ps1_r=' PS1='"'"'${debian_chroot:+($debian_chroot)}\\u\@ \\j\
                    \\h:\\w\\n\\$>'“'”'
 三十五
 36 sed -e "s/$srchPatt_wCtrls/$replPatt_wCtrls/" \
 37 -e "s/$ps1_o/#&\n$ps1_r/" ps1-tFILE.txt
 三十八
 39 退出

我的测试文件

对于那些对我的 ASCII 文本连接约定有疑问的人,我还包括了我的测试文件的内容(ps1-t文件.txt)在可滚动窗口中:

$> cat ps1-tFILE.txt
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
别的
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

再次感谢,它帮助我睡了一觉,并从中得到灵感斯科特:)

答案1

我不知道从哪里开始。如果你问过问题的话,我可能会从你问的问题开始,但我没有看到。

您说sed您提供的代码有效。但是对于我提供的文件,它不起作用,原因如下:

  • 您展示的文件已经有了 \n 在之前 \$(在第二个任务中 - 没有颜色代码的任务),但是您的ps1_2字符串包含“...... \\w\\$”(没有 ),所以它与文件中\n的不匹配 。\w\n\$
  • 同样,你的文件已经有了 > 在之后 \$(再次,在第二个任务中),但是您的ps1_2字符串以“ \\$ ”(没有 )结尾,因此它与文件中>的不匹配 。\$> 

此外,您的脚本使用\\$(in  ps1_2) 来匹配\$(in  .bashrc)。在您的脚本上下文中,这可能会起作用。但使用 可能更安全\\\$,因为\和 $都是特殊字符。请参阅下文了解更多信息。

如果你改变你的文件说

  if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
  else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$> '
  fi

(即删除\n第二个任务中的),并将脚本更改为

 ps1_2='    PS1='"'"'${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$> '"'"''
ps1_2n='    PS1='"'"'${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\n\\$> '"'"''

sed "s/$ps1_2/#&\n$ps1_2n/" ...

(即添加>到 ps1_2),那么它就会起作用。

显然,如果你的文件没有>之后已经有了\$,则不要将其添加到 ps1_2


但请考虑一下,

敏捷的棕色传真机跳过了那只懒狗。

嗯,这是错的。我们可以用以下方法修复它

s/The quick brown fax jumps over the lazy dog./The quick brown fox jumps over the lazy dog./

(可以选择以 结尾“旧”字符串\.,以确保),但为什么,当

s/a/o/

将工作?

PS1同样的,如果你的目标是“对于包含 的每一行赋值,将其注释掉,并用在 之前 \$插入 的赋值替换它 ”,那么你可以这样做\n\$

sed 's/\(.*PS1=.*\)\(\\$.*\)/#\1\2\n\1\\n\2/'

这将修复第 2 行和第 4 行,同时保留第 11 行(因为它不包含\$)。如果您的目标是“对于每个为 分配值的行,PS1 其中包含\$,请将其注释掉,并将其替换为 \n在 之前 插入 的赋值。\$ 以及 >之后 \$”,只是稍微复杂了一点:

sed 's/\(.*PS1=.*\)\(\\\$\)\(.*\)/#\1\2\3\n\1\\n\2>\3/'

请注意我必须在这里使用\\\$。我 猜测这是因为,当sed看到时,它会假设 表示 文字 <美元符号> ( ),而不是行尾,因为 不在 正则表达式的末尾,但是当它看到 时 ,它会感到困惑,因为 something$.*$$$\(…something$\)\(.*\)$ 在子表达式的末尾。这可能是 中的一个错误 sed

相关内容