Объясните выражение sed, которое удаляет строки с повторяющимися полями

Таблица маршрутизации — это не первое, что принимается во внимание при обработке пакета ядром; есть таблица правил, которая идет первой, которую вы можете увидеть с помощью ip rule list.ip route list( и устаревшийroute)перечисляют основную таблицу, но есть локальная таблица, которая имеет более высокий приоритет и содержит список всех маршрутов, связанных с петлевым интерфейсом; запустите ip route show table local, чтобы увидеть их.

Пакеты, адресованные петлевому адресу, не покидают систему.

5
11.07.2020, 22:56
2 ответа

Это базовые регулярные выражения (BRE )для sed по умолчанию, поэтому \(.\)— это группа захвата, содержащая один любой символ. Затем .*просто пропускает все, а \1соответствует тому, что соответствует группе. Если всю партию можно сделать совпадающей, то какой-то символ появился дважды, один раз для группы и один раз для обратной ссылки.

Фактически, если я не ошибаюсь, это не будет работать даже со стандартными расширенными регулярными выражениями, так как (по каким-то причинам )обратные ссылки в них не поддерживаются. Обратные ссылки упоминаются только в «BRE, соответствующие нескольким символам» , а не в ERE, и на самом деле то же самое с ERE не работает в моей macOS (, он принимает \1как буквальное номер1):

$ printf "%s\n" 122 321 | sed -E -e '/(.).*\1/d'
122

Однако инструменты GNU поддерживают обратные ссылки в ERE.

(Я не думаю, что sort -uздесь необходим, комбинация раскрытий фигурных скобок должна давать все комбинации без дубликатов.)

4
18.03.2021, 23:20

В качестве первого шага вам нужно правильно понять \(.\). В основных регулярных выражениях это группа захвата, захватывающая любой символ, который должен быть воспроизведен с помощью \1. Это не буквальные скобки.


Теперь самое интересное! Чему соответствует каждый элемент регулярного выражения в каждом случае?

     Left  \(.\) .*  \1  Right  Result
111        1      1   1          Deleted!
112        1          1   2      Deleted!
113        1          1   3      Deleted!
121        1      2   1          Deleted!
122  1     2          2          Deleted!
123        ?      ?   ?          NoMatch
131        1      3   1          Deleted!
132        ?      ?   ?          NoMatch
133  1     3          3          Deleted!      

На 122, если не ясно :Поскольку выражение не привязано, 1уходит влево, средний 2соответствует группе захвата \(.\), а последний 2соответствует обратная ссылка \1..*(ноль -или -больше символов, соответствующих регулярному выражению ), сделает все возможное, чтобы соответствовать строке, поэтому в этом случае она сжимается до нулевой строки.

Если сомневаетесь, попробуйте

echo 122 | grep --color=always '\(.\).*\1'

Вы увидите, что только 22был окрашен.


Сравните его с закрепленной версией регулярного выражения:

$ printf "%s\n" {1,2,3}{1,2,3}{1,2,3} | sort -u | sed '/^\(.\).*\1$/d'
112
113
122
123
132
133
...

Теперь нет слотов "Левый" и "Правый":

     ^\(.\) .*  \1$  Result
111  1       1   1    Deleted!
112  ?       ?   ?    NoMatch
113  ?       ?   ?    NoMatch
121  1       2   1    Deleted!
122  ?       ?   ?    NoMatch
123  ?       ?   ?    NoMatch
131  1       3   1    Deleted!
132  ?       ?   ?    NoMatch
133  ?       ?   ?    NoMatch

Первая цифра должна быть последней цифрой в этой версии, чтобы совпадений было меньше.

5
18.03.2021, 23:20

Теги

Похожие вопросы