![使用 sed 将具有特殊字符的字符串替换为另一个具有特殊字符的字符串](https://linux22.com/image/64705/%E4%BD%BF%E7%94%A8%20sed%20%E5%B0%86%E5%85%B7%E6%9C%89%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%9B%BF%E6%8D%A2%E4%B8%BA%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%85%B7%E6%9C%89%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我正在尝试自动将 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
'sc
(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
。