我有以下脚本:
#!/bin/bash
LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1"
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline"
#sed -i "/${LINE}/c ${NEW_LINE}" grub.cfg
LINE1="insmod lvm"
NEW_LINE1="insmod lvm x"
sed -i "/${LINE1}/c ${NEW_LINE1}" grub.cfg
有人可以告诉我为什么评论的sed不起作用(错误:sed: -e expression #1, char 10: extra characters after command
),但是当只有字符串不同时,未注释的sed会这样做吗?
答案 0 :(得分:1)
由于您要查找的行中有斜杠,因此您需要使用不同的字符来标记s///
命令的边界。例如,字符串中没有任何%
符号,因此:
LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1"
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline"
sed -i "s%.*${LINE}.*%${NEW_LINE}%" grub.cfg
或者,保持更改命令,您需要在匹配中使用不同的字符 - 在它前面使用反斜杠来表示您正在做的事情。
LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1"
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline"
sed -i "\%${LINE}%c ${NEW_LINE}" grub.cfg
sed
的POSIX规范说:
sed实用程序应支持XBD Basic正则表达式中描述的BRE,并添加以下内容:
- 在上下文地址中,构造“
\cBREc
”,其中c
是<backslash>
或<newline>
以外的任何字符,应与“{{1}相同}”。如果/BRE/
指定的字符出现在c
之后,则应将其视为该字面字符,该字符不应终止BRE。例如,在上下文地址“<backslash>
”中,第二个\xabc\xdefx
代表自己,因此BRE为“x
”。
和
abcxdef
将替换字符串替换为模式空间中BRE的实例。可以使用[2addr]s/BRE/replacement/flags
或<backslash>
以外的任何字符代替<newline>
来分隔BRE和替换字符。在BRE和替换中,如果BRE分隔符前面有<slash>
,则它可以用作文字字符。
答案 1 :(得分:0)
未注释的行无法使用,因为sed
表达式使用的分隔符出现在您要匹配和替换的内容中。
LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1"
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline"
sed -i "/${LINE}/c ${NEW_LINE}" grub.cfg
您的sed
表达式将解析为:
/linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1/c linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline
如您所见,这导致表达式中的操作比sed预期的更多,因此您的错误消息为extra characters after command
。
如果您将分隔符更改为其他字符,则应该有效:
sed -i "\:${LINE}:c ${NEW_LINE}" grub.cfg
您也可以使用s
命令 - 尝试:
sed -i "s:${LINE}:c ${NEW_LINE}:g" grub.cfg