Удалить используя другой разделитель с Sed

Совершенно уверен, что мне не хватает чего-то очевидного!

$ cat test.txt
  00 30 * * * /opt/timebomb.sh >> timebomb.log
  01 30 * * * /opt/reincarnate.sh >> reincarnation.log
$ sed ':timebomb:d' test.txt
  00 30 * * * /opt/timebomb.sh >> timebomb.log
  01 30 * * * /opt/reincarnate.sh >> reincarnation.log

в то время как

$ sed '/timebomb/d' test.txt
  01 30 * * * /opt/reincarnate.sh >> reincarnation.log

Почему это так? Не поддерживается ли другой набор разделителей для d команда?

4 ответа

Решение

Разделители // что вы используете не для d Команда, они для адресации. Я думаю, что вы сравниваете их с косой чертой в s/// команда... Однако, хотя оба относятся к регулярным выражениям, они имеют разные контексты.

Адрес (который появляется перед командой) фильтрует, к каким строкам применяется команда... Параметры (которые появляются после команды) используются для управления примененной заменой.

Если вы хотите использовать разные разделители для регулярного выражения в адресе, вам нужно начинать адрес с обратной косой черты:

$ sed '\:timebomb:d' test.txt
  01 30 * * * /opt/reincarnate.sh >> reincarnation.log

(Чтобы понять разницу между адресом и параметрами, рассмотрите вывод команды:

$ sed '/timebomb/s/log/txt/' test.txt

Адрес выбирает только те строки, которые содержат регулярное выражение timebomb, но варианты сообщают s команда для замены регулярного выражения log с txt.)

Двоеточие предшествует метке в sed, поэтому ваша программа sed выглядит как пара меток, и ничего не происходит. Парсер может видеть двоеточия как разделители, если им предшествует команда s, так что это особый случай.

Использовать тараканы

gawk '!/timebomb/' file > newfile

Вы можете просто использовать оболочку, не нужно внешних инструментов

while read -r line
do 
    case "$line" in
        *timebomb* ) continue;;
        *) echo "$line";;
    esac        
done <"file"
Другие вопросы по тегам