使用 sed 将具有特殊字符的字符串替换为另一个具有特殊字符的字符串

使用 sed 将具有特殊字符的字符串替换为另一个具有特殊字符的字符串

我正在尝试自动将 bash 提示符切换为 .bashrc 中的另一个提示符

原始字符串:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

替换弦:

IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
PS1='\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] '

编写 bash 来做到这一点的许多糟糕尝试之一:

#!/bin/bash
original="PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '"
replacement="PS1='\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] '" 
ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print \$2}' | cut -c 6- )"

cp ~/.bashrc ~/.bashrc.bak
sed -e 's/$original/$replacement/g' ~/.bashrc

我尝试过对所有字符进行双重转义,因为我知道 sed 需要转义 '\'、'/' 和 '&'。我似乎无法理解这个问题。

我什至没有费心尝试立即将 IP 线路插入其中,因为我无法更换第一条线路。

如果这种类型的自动化有任何更好的方法,请告诉我。

答案1

这里有几种方法(好吧,2.5):

  • 如果您有兴趣能够逐步修改PS1遵循通用模板的设置,

    • 创建一个仅包含该行的文件PS1=…
    • 编写sed命令来逐段编辑它;例如,
      • sed -e 's/${debian_chroot:+($debian_chroot)}/\\d \\t /'
      • sed -e 's/\\033/\\e/g'
      • ETC。
    • 您可能会发现调试这些更小、更简单的命令更容易。当你让它们全部工作起来后,将它们拼接在一起应该很简单。
    • 看着的价值$original?例如,你做完了吗
              printf "%s\n" "$original"
      ?请记住,当你说类似的话时

      "The quick brown fox 'jumps over' the lazy dog."
      

      整个字符串位于双倍的引号。所以当你说

      "Humpty '$var' Dumpty"
      

      $var扩展,因为它用双引号引起来。

      现在看看你的original字符串:

      original="PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:…"
      

      ${debian_chroot:+($debian_chroot)}当您进行该分配时,范围会扩大。所以这是一个问题。

  • 如果你只是想改变PS1你的新值,不管已经有什么,不要试图凿掉狐狸的雕像,然后添加粘土,希望创造一个狗的雕像;只需删除现有的分配并替换它,使用sed's c(Change) 命令,它将一组一行或多行替换为另一组一行或多行:

    sed -e $'/^PS1=/c\
    IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk \'{print $2}\' | cut -c 6- )\
    PS1=\'\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] \''
    

    我将整个sed命令字符串放入其中,$'…' 以便我可以\'将原始'字符放入字符串中。如果您愿意,您可以使用经过验证的真实方法

    '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'
    

    (引用交替)技术。

  • 上面的一个变体是

    sed -e $'/^PS1=/{s/^/# /; a\
    IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk \'{print $2}\' | cut -c 6- )\
    PS1=\'\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] \'
    }'
    

    它注释掉了现有的定义 ( s/^/# /) 和A使用该命令追加新行a

相关内容