在以下示例fstab
文件中,我们要删除以 开头的所有行UUID
,但包含单词UUID
的行除外boot
/dev/mapper/VG100-lv_root / xfs defaults 0 0
UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot xfs defaults 0 0
/dev/mapper/VG100-lv_var /var xfs defaults 0 0
UUID=0b14011d-f69d-4c4c-8ce0-6240bb0a574a /var/kafka/mp1 xfs defaults,noatime 0 0
UUID=2d7872f2-96d4-4ba9-8a17-a1115542645c /var/kafka/mp2 xfs defaults,noatime 0 0
UUID=79bdbf56-9a09-4505-ab8e-41ce9432cf0f /var/kafka/mp3 xfs defaults,noatime 0 0
UUID=ca42a388-83d4-4f8b-aff7-3450d836eef7 /var/kafka/mp4 xfs defaults,noatime 0 0
UUID=62d356bb-c393-4a74-bbf9-984b60d3b5c4 /var/kafka/mp5 xfs defaults,noatime 0 0
UUID=d4071a83-204f-475f-8917-cdd77ef6b1ed /var/kafka/mp6 xfs defaults,noatime 0 0
所以例外的结果应该如下
/dev/mapper/VG100-lv_root / xfs defaults 0 0
UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot xfs defaults 0 0
/dev/mapper/VG100-lv_var /var xfs defaults 0 0
到目前为止我们有以下 sed
sed -i '/^UUID/d' /etc/fstab
但上述方法会删除所有UUID
行
答案1
在我看来,您想删除第一个字段以 开头UUID=
而第二个字段不是 的行/boot
。
所以awk
or perl 的 awk 模式似乎是一个明显的选择:
awk '! ($1 ~ /^UUID=/ && $2 != "/boot")' /etc/fstab
(GNU awk 可以使用¹进行就地编辑-i /usr/share/awk/inplace.awk
)。
perl -lae 'print unless $F[0] =~ /^UUID=/ && $F[1] ne "/boot"' /etc/fstab
(perl
用于-i
就地编辑)。
可以使用以下方法完成等效操作sed
:
sed '/^[[:space:]]*[^[:space:]]\{1,\}[[:space:]]\{1,\}/boot\([[:space:]].*\)\{0,1\}$/b
/^[[:space:]]*UUID=/d' /etc/fstab
有些可以使用(大多数)或(FreeBSD 及其衍生产品,包括 Macos)sed
进行就地编辑。-i
-i ''
^不使用-i inplace
as尝试首先从当前工作目录gawk
加载inplace
扩展(asinplace
或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk
的路径可能会有所不同,请参阅输出inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
答案2
首先告诉 sed 打印包含 的行boot
,然后告诉它删除包含 的行UUID
,用 分隔表达式;
sed -i '/boot/p;/UUID/d' /etc/fstab
由于打印表达式是在删除表达式之前给出的,因此在删除带有 UUID 的行之前将打印包含 boot 的行,如果您要更改表达式位置,则这是行不通的。
鉴于你给出的例子,你应该得到这样的东西
/dev/mapper/VG100-lv_root / xfs defaults 0 0
UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot xfs defaults 0 0
/dev/mapper/VG100-lv_var /var xfs defaults 0 0
您还可以添加部分来删除空行,^
标记行的开头,并$
标记行的结尾,因此添加表达式来删除$
在行开头之后有行结尾的行^
。
sed -i '/boot/p;/UUID/d;/^$/d' /etc/fstab
编辑
正如 Stéphane Chazelas 的评论中所指出的,如果同一行中不包含 UUID,这将打印包含 boot 的行两次,所以这样的事情会更好。
sed -i '/^UUID/{/boot/!d};/^$/d' /etc/fstab
它将删除以 UUID 开头的行,除非它们包含 /boot,然后删除所有空行
答案3
有很多可能性。保持简单,您可以使用
'/^UUID/{
/\/boot/b
d
}'
它用于{}
包含模式匹配时要执行的更多命令。如果 boot 匹配,b
则分支到命令末尾,否则完成d
。或者,
'/^UUID/{
/\/boot/!d
}'
如果启动是不是匹配,进行删除。这些模式应该通过匹配空白来增强,但如果您了解文件中的期望,您可能不会关心。
单行版本可能不适用于某些版本sed
:
'/^UUID/{/\/boot/b;d;}'
和
'/^UUID/{/\/boot/!d;}'