Как заставить sed «скрипт» перезапустить сопоставление вместо выхода («повторить» вместо команды «выйти»)? - PullRequest
0 голосов
/ 11 марта 2019

Я извиняюсь, если на этот вопрос уже был дан ответ, но я искал этот сайт и несколько его сообществ и не смог найти никакой информации по этой теме.

Я часто использую эту общую команду sed, чтобы распечатать всестроки от строки, совпадающей с STARTPAT до, но не включающей строки, совпадающей с ENDPAT:

sed -rn '/STARTPAT/,/ENDPAT/{/STARTPAT/{p;n};/ENDPAT/{q};p}' FILE

Однако это не может соответствовать нескольким разделам FILE из-за значения qкоманда для предотвращения печати второй подходящей строки (или, по крайней мере, я думаю в этом причина).

Я хотел бы иметь возможность применить эту же концепцию глобально но не могу заставить его работать должным образом.Я пытался применить команду g lobal к различным точкам, в которых шаблоны сопоставляются, а также комбинируются с командами p и n, и я также пытался использовать методы «хранения» напечатанного вывода, чтобы просто напечатать еговсе в конце (аналогично использованию sed для печати абзацев, содержащих совпадение).Может быть, я просто не понимаю, как именно g lobal команда или диапазоны в целом.

Я также просматривал справочную страницу для sed и несколько sed учебных пособий онлайн вВ случае, если для sed уже есть встроенная команда, которая ведет себя как q, но вместо выхода она повторяет предоставленный «скрипт» и забывает ранее сопоставленные строки (чтобы не пропустить соответствующий раздел, который следует сразу задругой соответствующий раздел, поскольку первое совпадение для этого следующего раздела - это та же строка, которая была проигнорирована в предыдущем сопоставлении).

Дайте мне знать, будет ли полезна какая-либо дополнительная информация.Заранее благодарен за любую помощь, которую я могу получить, даже если я далеко от базы или прошу что-то, чего просто не существует.

ОБНОВЛЕНО ПО ЗАПРОСУ [2019-Mar-11]:

Использование оригинального решения , предоставленного John1024 ,Конкретная команда, которую я пытался создать:

apt-cache depends --recurse --no-suggests --no-recommends --no-conflicts \
--no-breaks --no-replaces --no-enhances gdm3 | \
sed -rn '/^\S*(unity|ubuntu|desktop|session)/,/^\S+/{/^\S*(unity|ubuntu|desktop|session)/{p;n};/^\S+/d;p}'

Вот несколько примеров вывода:

  Depends: libxtst6
gnome-session
  Depends: gnome-settings-daemon
gnome-session-flashback
  Depends: dbus-user-session
    dbus-user-session:i386
  Depends: gnome-session-bin
  Depends: gnome-session-common
  Depends: gnome-settings-daemon
  Depends: indicator-common
  Depends: nautilus
  Depends: systemd
    systemd:i386
lxqt-session
  Depends: libc6

Когда я использую упрощенное решение, предоставленное John1024 :

apt-cache depends --recurse --no-suggests --no-recommends --no-conflicts \
--no-breaks --no-replaces --no-enhances gdm3 | \
sed -rn '/^\S*(unity|ubuntu|desktop|session)/,/^\S+/{/^\S+/d;p}'

вывод не содержит любых строк, соответствующих /^\S+/, что означает, что не отображаются имена зависимостей верхнего уровня, а некоторые наборы зависимостей, которые должны отображаются полностью пропущены.Вот фрагмент вывода, который в идеале совпадал бы с предыдущим примером:

  Depends: libxtst6
  Depends: dbus-user-session
    dbus-user-session:i386
  Depends: gnome-session-bin
  Depends: gnome-session-common
  Depends: gnome-settings-daemon
  Depends: indicator-common
  Depends: nautilus
  Depends: systemd
    systemd:i386
  Depends: libc6
  Depends: libglib2.0-0
  Depends: libgtk2.0-0
  Depends: libx11-6
  Depends: lsb-release

Ранее существовавшая команда, на которую я ссылался в исходном вопросе, которую я использую как часть функции bash для извлечения абзаца Description из вывода apt-cache show одного или нескольких пакетов, выглядит так:

apt-cache show ${pkg} | \
sed -rn '/^Description(-en)?/,/^[^: ]+:/{/^Description(-en)?/{p;n};/^[^: ]+:/{q};p}'

Ответы [ 2 ]

2 голосов
/ 11 марта 2019

Попробуйте:

sed -rn '/STARTPAT/,/ENDPAT/{/STARTPAT/{p;n};/ENDPAT/d;p}' file

Разница в том, что вместо выхода (q) при достижении ENDPAT мы просто удаляем эту нежелательную строку (d).

Пример

Рассмотрим этот тестовый файл:

$ cat file
omit 1
STARTPAT
keep 1
ENDPAT
omit 2
STARTPAT
keep 2
ENDPAT
omit 3

Запустим нашу команду:

$ sed -rn '/STARTPAT/,/ENDPAT/{/STARTPAT/{p;n};/ENDPAT/d;p}' file
STARTPAT
keep 1
STARTPAT
keep 2

Упрощение

$ sed -rn '/STARTPAT/,/ENDPAT/{/ENDPAT/d;p}' file
STARTPAT
keep 1
STARTPAT
keep 2
1 голос
/ 11 марта 2019

Если вы согласны с awk, я также добавляю вариант awk.

awk '/ENDPAT/{flag=""}  /STARTPAT/{flag=1} flag'  Input_file

Принимая пример файла Input_file, который @ John1024 опубликовал в своем сообщении.

cat Input_file
omit 1
STARTPAT
keep 1
ENDPAT
omit 2
STARTPAT
keep 2
ENDPAT
omit 3

После выполнения кода мы получим следующий вывод.

awk '/ENDPAT/{flag=""}  /STARTPAT/{flag=1} flag'  Input_file
STARTPAT
keep 1
STARTPAT
keep 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...