Удаление строк файла с sed - неожиданное поведение

Я заметил что-то немного странное, обманывая с sed. Если вы попытаетесь удалить несколько строк (по номеру) из файла, но любой интервал, указанный позже в списке, полностью содержится в интервале ранее в списке, то после указанного (большего) интервала удаляется дополнительная одиночная строка.

seq 10 > foo.txt

sed '2,7d;3,6d' foo.txt
1
9
10

Такое поведение было вызвано раздражающей ошибкой для меня, так как в моем script я создал интервальные конечные точки "на лету", а в некоторых случаях полученные интервалы были избыточными. Я могу это очистить, но я не могу придумать, почему sed будет вести себя так специально.

Ответ 1

Поскольку этот вопрос был подсвечен как необходимость ответа в еженедельном бюллетене по рассылке стека по электронной почте для 2015-02-24, я перехожу к комментариям выше (которые предоставляют ответ) в формальный ответ. Безрецептурные комментарии здесь были сделаны мной в существенно эквивалентной форме.

Спасибо за краткий, полный вопрос. Результат интересен. Я могу воспроизвести его с помощью script. Интригующе, sed '3,6d;2,7d' foo.txt (с операциями удаления в обратном порядке) дает ожидаемый ответ с 8 включенными в выход. Это делает его похожим на отчетную ошибку в (GNU) sed, тем более что BSD sed (в Mac OS X 10.10.2 Yosemite) корректно работает с операциями в любом порядке. Я тестировал, используя "sed (GNU sed) 4.2.2" из производной Ubuntu 14.04.

Дополнительные данные для вас/них. Оба они включают 8 в выход:

sed -e '/2/,/7/d' -e '/3/,/6/d' foo.txt
sed -e '2,7d' -e '/3/,/6/d' foo.txt

В отличие от этого, это не означает:

sed -e '/2/,/7/d' -e '3,6d' foo.txt

Последний удивил меня (даже принимая основную ошибку).

Ударь меня. Мне показалось, что некоторые из sed загадочных конструкций, которые могут отсутствовать у символа batman или что-то из середины вашей команды, но sed -e '2,7d' -e '3,6d' foo.txt ведет себя одинаково, и замена порядка приводит к ожидаемым результатам (GNU sed 4.2.2 на Cygwin). /bin/sed в Solaris всегда производит ожидаемый результат, и интересно, так же как и GNU sed 3.02. Эд Мортон

Дополнительные данные: кажется, что это происходит только с sed 4.2.2, если второй диапазон является подмножеством первого: sed '2,5d;2,5d' показывает ошибку, sed '2,5d;1,5d' и sed '2,5d;2,6d' этого не делают. glenn jackman

На главной странице GNU sed говорится: "Пожалуйста, отправьте сообщения об ошибках в bug-sed на gnu.org" (кроме того, @вместо 'at'). У вас хорошее воспроизведение; будьте откровенны в отношении вывода, который вы ожидаете, за результат, который вы получаете (они поймут смысл, но лучше всего убедиться, что они не могут понять неправильно). Укажите, что обратный порядок команд работает так, как ожидалось, и дает различные другие команды в качестве примеров работы или отсутствия работы. (Вы даже можете указать этот URL-адрес Q & URL как перекрестную ссылку, но убедитесь, что отчет об ошибке является автономным, чтобы его можно было понять, даже если никто не следует за URL-адресом.)

Вы также можете указать BSD sed (и версию Solaris, а также более старый GNU 3.02 sed), как и ожидалось. При работе старой версии GNU sed это означает, что это, возможно, регрессия. [... После небольшого эксперимента...] Поломка произошла в версии 4.1; релиз 4.0.9 в порядке. (Я также проверил 4.1.5 и 4.2.1, оба они сломаны.) Это поможет сопровождению, если они хотят найти проблему, посмотрев, что изменилось.

ОП отметил:

  • Спасибо всем за комментарии и дополнительные тесты. Я отправлю отчет об ошибке в GNU sed и опубликую ответ. santayana