2015-02-18 2 views
11

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

seq 10 > foo.txt 

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

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

+4

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

+3

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

+4

На домашней странице [GNU 'sed'] (http://www.gnu.org/software/sed/) говорится:« Пожалуйста, отправьте сообщения об ошибках в bug-sed на gnu.org »(кроме того, что он имеет' @ 'в место 'at'). У вас хорошее воспроизведение; быть в явном виде о выходе, который вы ожидаете, и о том, какой результат вы получите (они поймут смысл, но лучше всего убедиться, что они не могут неправильно понять). Укажите, что обратный порядок команд работает так, как ожидалось. Вы также можете указать BSD 'sed' (и версию Solaris, а также более старую версию GNU 3.02' sed'), как и ожидалось. При использовании старой версии GNU 'sed', это означает, что это, возможно, регрессия. –

ответ

5

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

Благодарим за сжатый, полный вопрос. Результат интересен. Я могу воспроизвести его с помощью вашего скрипта. Интригующе, 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 

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

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

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

GNU sed домашняя страница говорит «Пожалуйста, присылайте сообщения об ошибках на баг-SED в gnu.org» (кроме него есть @ вместо «в»). У вас хорошее воспроизведение; быть в явном виде о выходе, который вы ожидаете, и о том, какой результат вы получите (они поймут смысл, но лучше всего убедиться, что они не могут неправильно понять). Укажите, что обратный порядок команд работает так, как ожидалось, и дает различные другие команды в качестве примеров работы или отсутствия работы.(Вы могли бы даже дать это 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
+1

Спасибо, что поставили это вместе. У меня есть подтверждение от GNU sed, что это действительно ошибка, и они отправили мне патч, который мне еще не удалось успешно реализовать. Как только я могу подтвердить, что исправление исправляет поведение, я опубликую его. – santayana

Смежные вопросы