【问题标题】:Incorrect escaping for regex expression in sed; I don't want a literal TAB, I want \tsed 中的正则表达式转义不正确;我不想要文字 TAB,我想要 \t
【发布时间】:2016-04-08 15:05:05
【问题描述】:

我正在尝试运行脚本来修改.bashrc 以在命令提示符前插入时间。但我一直以文字 TAB 结束。

我试过了

sed -i "s/PS1='\${deb/PS1=\'\\t \${deb/" {filename}
sed -i "s/PS1='\${deb/PS1='\\t \${deb/" {filename}
sed -i "s/PS1='\${deb/PS1='\t \${deb/" {filename}
sed -i 's/PS1=\'\${deb/PS1=\'\\t \${deb/' {filename}
sed -i $'s/PS1=\'\${deb/PS1=\'\\t \${deb/' {filename}

以及上述的许多变体。我通常不会在实际标签中插入任何内容。

我发现如果我这样做:

sed $'s/PS1=\'\${deb/PS1=\'\\t \${deb/' {filename} | grep PS1=

然后我得到的输出似乎是我所追求的,但不是在文件中。

如何将实际的 \t而不是 TAB 插入到我要编辑的文件中?

如果不是很明显,上面的最后一个示例和命令行上的测试使用相同的正则表达式。或者至少,我认为他们会这样做。

我试图更改.bashrc 中的两行。这些行与命令提示符有关,并在此处完整复制:

~⟫ grep PS1 .bashrc
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\$ '
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"

我希望将其转换为:

PS1='\t ${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
PS1='\t ${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"

我认为这很明显,但是我不想在该行中插入 TAB。我想按字面意思插入\t,即“反斜杠和t”在一起,而不是将它们翻译成TAB。

【问题讨论】:

  • 听起来 OP 正在尝试 not 插入标签!
  • sed -e 's/pattern/\\t/g' /tmp/file >/tmp/newfile 对我来说就像一个魅力
  • 我尝试了单引号和双引号中的三重反斜杠。我认为我没有尝试过-e 开关。愚蠢的部分是最后一个标准输出,只是不符合要求。
  • 感谢@Aaron 的想法,尽管它们可能是不正确的 :) 汤姆(和我的问题)总结了一下,我不想要标签。请至少完整阅读标题(我没有更改它)或至少略读问题;)

标签: regex bash


【解决方案1】:

当您在 sed 命令周围使用双引号时,您还需要转义 \,即在替换字符串中使用 \\\t。这是因为 shell 在 sed 看到之前将 \\ 转换为 \,因此如果您以 \\t 开头,那么您最终会以 \t 结尾,并且 sed 会插入一个制表符。

如果您在命令周围使用单引号,那么您不必双重转义,因为 sed 会看到 \\t。但是,您的模式似乎包含单引号。

根据您的尝试猜测,您需要使用以下内容:

sed -E -i.bak "s/(PS1=')(\\$\\{deb)/\\1\\\t\\2/" .bashrc

我使用捕获组来减少重复。对捕获组的引用也需要转义。我还在-i 开关上添加了一个后缀,以便备份您的原始文件。

如果您向我们展示文件中的当前行和所需的输出,那么我们可以为您提供准确的答案。

【讨论】:

  • 我回家后会添加整行,但它与.bashrc 的命令提示设置基本相同。我可能只是在脚本末尾附加一个前缀就可以逃脱,只是我总是在那里手动添加它。我认为这一切都被该行中的字符混淆了,即\t, \, $, {, ', " 可能还有其他人:)
  • 参考我的问题中的编辑,但它是三个反斜杠。稍后我将回顾 bash 历史,我知道我试过了,但它可能在单引号或其他我不确定的东西后面。尽管如此,这是正确的。谢谢:)
【解决方案2】:

你需要双重转义\t:

 sed -i "s/PS1='\${deb/PS1='\\\t \${deb/" .bashrc

sed 删除了转义级别,并将在您的文件中插入文字 \t

【讨论】:

  • 重温这个之后,我把正确答案改成了这个。这两个答案都是正确的,我确实喜欢汤姆的“小组”方法,我应该经常这样做,但这是我使用的确切答案,因此,谢谢 Ben :)
猜你喜欢
  • 2013-12-23
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
相关资源
最近更新 更多