Rgex не работает с командой sed, как ожидалось

#regex #linux #shell #sed

Вопрос:

У меня есть текстовый файл, содержащий :

А 25 27 50

В 35 75

С 75 78

Д 99 88 76

Я хотел удалить строку, в которой нет четвертого поля(четвертой пары цифр). Ожидаемый результат :

А 25 27 50

Д 99 88 76

Я знаю, что команда awk была бы лучшим вариантом для такой задачи, но мне интересно, в чем проблема с моей командой sed, так как она должна работать, как вы можете видеть ниже :

 sed -E '/^[ABCD] ([0-9][0-9]) 1$/d' text.txt
 

Использование POSIX ERE с обратными ссылками (1) для ссылки на предыдущий шаблон, заключенный в круглые скобки.

Вместо этого я попробовал эту команду :

 sed -E '/^[ABCD] ([0-9][0-9]) [0-9][0-9]$/d' text.txt
 

Но, похоже, он удаляет только первое вхождение того, что я хочу.
Я был бы признателен за дальнейшее объяснение,

  • почему обратная ссылка работает не так, как ожидалось.
  • что случилось с первым появлением во второй попытке,должен ли я включить глобальную опцию, если да, то как, так как я уже пытался добавить ее в конце вместе с /d (для удаления), но это не сработало .

Ответ №1:

Намного проще с awk :

 awk 'NF == 4' file

A 25 27 50
D 99 88 76
 

Эта awk команда использует разделитель полей по умолчанию в виде пробела или вкладки и проверяет условие NF == 4 , чтобы убедиться, что мы печатаем строки только с 4 полями.


С sed этим было бы (при условии, что в каждой строке нет начальных конечных пробелов):

 sed -nE '/^[^[:blank:]] ([[:blank:]] [^[:blank:]] ){3}$/p' file

A 25 27 50
D 99 88 76
 

Комментарии:

1. @Ayoub_Prog: Это сработало?

Ответ №2:

С вашими показанными образцами в sed программе вы можете попробовать следовать. Написано и протестировано в GNU sed .

 sed -nE '/^([^[:space:]] [[:space:]] ){3}[^[:space:]] $/p' Input_file
 

Пояснение: Просто остановите печать для строк по sed -n выбору. Затем используется -E для использования ERE в программе. В основной программе используется регулярное выражение для сопоставления с начала без пробелов(1 или более вхождений), за которым следуют пробелы(1 или более вхождений) и эта комбинация 3 раза(в основном для сопоставления 3 полей), за которой следуют без пробелов 1 или более вхождений до конца значения строки, если это регулярное выражение соответствует, затем выведите эту строку.

Ответ №3:

Это может сработать для вас (GNU sed):

 sed -En 's/S /amp;/4p' file
 

Отключите неявную печать -n и включите расширенное регулярное -E выражение .

Подставьте 4 — е поле само по себе и распечатайте результат.