Sed: Как удалить строки, соответствующие шаблону, содержащему косые черты?

Предположим, что файл /etc/fstab содержит следующее:

/dev/xvda1 / ext4 defaults 1 1
/dev/md0    /mnt/ibsraid    xfs defaults,noatime    0   2
/mnt/ibsraid/varlog /var/log    none    bind    0   0
/dev/xvdb   None    auto    defaults,nobootwait 0   2

Я хочу удалить строку, начинающуюся с /dev/xvdb. Поэтому я попробовал:

$ sed '/^/dev/xvdb/d' /etc/fstab
sed: -e expression #1, char 5: extra characters after command
$ sed '?^/dev/xvdb?d' /etc/fstab
sed: -e expression #1, char 1: unknown command: `?'
$ sed '|^/dev/xvdb|d' /etc/fstab
sed: -e expression #1, char 1: unknown command: `|'

Ничего из этого не получилось. Я попытался изменить разделители на ? и |, потому что это работает для команды подстановки sed, когда шаблон содержит /.

Я использую GNU Sed 4.2.1 на Debian.

Ответ 1

Ты был очень близок. Когда вы используете нестандартный символ для разделителя шаблонов, например |pattern|, первое использование этого символа должно быть экранировано:

$ sed '\|^/dev/xvdb|d' /etc/fstab
/dev/xvda1 / ext4 defaults 1 1
/dev/md0    /mnt/ibsraid    xfs defaults,noatime    0   2
/mnt/ibsraid/varlog /var/log    none    bind    0   0

Аналогичным образом можно использовать:

sed '\?^/dev/xvdb?d' /etc/fstab

Наконец, можно использовать косые черты внутри /pattern/, если они экранированы так, как вы показали в своем ответе.

Ответ 2

После некоторого копания я обнаружил, что в строке шаблона можно избежать /, используя \. Итак, это работает:

$ sed '/^\/dev\/xvdb/d' /etc/fstab

Ответ 3

Почему одержимость использованием косой черты в качестве разделителя? Просто используйте что-то еще, как запятую:

sed ',^/dev/xvdb,d' /etc/fstab

или двоеточие:

sed ':^/dev/xvdb:d' /etc/fstab

Или все, что облегчает чтение. Разделителем может быть любой символ. Соглашение заключается в использовании косой черты, но когда это становится неудобным, переключите его на что-то еще.

Обратите внимание, что если вы хотите изменить сам файл, а не выводить результат, вам нужен флаг "на месте" -i:

sed -i ':^/dev/xvdb:d' /etc/fstab