我想改变PS1
在我的程序中,~/.bashrc
可以使用任何最流行的正则表达式工具 {sed
或}。但是,我遇到了问题awk
perl
特殊字符。请注意,默认情况下,在不同条件下设置~/.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,3和3}} 但我相信 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
。