Вложенный awk захватывает определенную строку из второго совпадения и отображает

#bash #awk #sed

#bash #awk #sed

Вопрос:

У меня есть содержимое файла в виде

 0::chkconfig --list autofs::
 autofs                 0:off   1:off   2:on    3:on    4:on    5:on    6:off

1::grep "^PROMPT=" /etc/sysconfig/init::
 PROMPT=yes

2::rpm -q prelink::
 prelink-0.4.0-2.el5

3::sysctl fs.suid_dumpable::
 fs.suid_dumpable = 0

4::stat /etc/motd::
   File: `/etc/motd'
  Size: 17              Blocks: 16         IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 10125343    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-04-08 07:54:03.000000000  0500
Modify: 2019-03-30 19:22:13.000000000  0500
Change: 2019-03-30 19:22:13.000000000  0500

5::stat /etc/issue::
   File: `/etc/issue'
  Size: 52              Blocks: 16         IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 10125494    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-03-30 19:12:13.000000000  0500
Modify: 2012-02-25 22:01:14.000000000  0500
Change: 2019-03-30 23:54:57.000000000  0500
  

Я хочу, чтобы первое совпадение захватило everything меня между
:: <everything>d::

примечание: :: за ним следует новая строка n (хотите пропустить сначала ::)

d для регулярного выражения может быть 3 места 999 (максимум).

Второе совпадение заключается в поиске в первом совпадении, например, для 5::

Access: (0644/-rw-r--r--)

захват доступа 0644

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

Результатом окончательного совпадения будет только совпадающая строка, а не вся запись или результат.

Итак, пока я пробовал с cat org_op.2019.04.08-12.49.38 | awk 'f{print;f=0} /^3::/{f=1}'

что даст мне

 ` fs.suid_dumpable = 0`
  

но его не масштабирование до многострочных совпадений дает только 1 строку ниже совпадения

Я также пытаюсь, awk -F [::,d""] но не могу получить совпадение регулярных выражений d между скобками.

КОНЕЧНЫЙ РЕЗУЛЬТАТ

 4::stat /etc/motd::
   File: `/etc/motd'
  Size: 17              Blocks: 16         IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 10125343    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-04-08 07:54:03.000000000  0500
Modify: 2019-03-30 19:22:13.000000000  0500
Change: 2019-03-30 19:22:13.000000000  0500
  

УСЛОВИЕ # 1
Какой блок получить, вводится пользователем, например, для начального тега d:: где ‘d’ предоставляется пользователем, и он завершится до начала нового блока, также объясненного выше.

УСЛОВИЕ # 2 Смотрите fd00h/64768d , но это условие будет изменено и будет записано уникальным для каждого блока, которому соответствует его переменная, я хочу awk, который я могу увеличить на основе этих требований к форматированию.

ПРИМЕЧАНИЕ: из предоставленных пользователем я имею в виду, что она должна быть задана как переменная, например, $ var

ТЕСТИРОВАНИЕ

cat org_op.2019.04.08-12.49.38 | awk -v id=4 -v RS= -F ':' '($1==id) amp;amp; $17~/(([0-9] )// { print $17}'

(0644/-rw-r--r--) Uid

Где-фактически я хочу, чтобы это регулярное выражение соответствовало /([0-9][0-9][0-9][0-9]//) 0644

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

1. не могли бы вы добавить свой вывод для этого ввода? Спасибо

2. @Allan см. Обновление, пожалуйста

3. d является сокращением для [[:digit:]] in PCREs . Очень немногие инструменты командной строки поймут, что вы имеете в виду, когда пишете d . Просто используйте [[:digit:]] или [0-9] вместо этого для переносимости ко всем инструментам POSIX. Сказав это, можете ли вы уточнить и / или упростить свой пример? Я чувствую, что все, что вы пытаетесь сделать, должно быть тривиальным, но пока я не могу понять ваше объяснение того, что вы пытаетесь сделать.

4. Спасибо @EdMorton, какую часть сложнее понять, я могу улучшить понимание.

5. The second match is to search within the first match for e.g for 5:: — Существует только 1 блок, который начинается с 5:: , и ваш ожидаемый результат — это блок, который начинается с. 4:: Итак, что это значит?

Ответ №1:

Это все, что вы пытаетесь сделать?

 $ awk -v id=4 -v str='Access: (0644/-rw-r--r--)' -v RS= -F':' '($1==id) amp;amp; index($0,str)' file
4::stat /etc/motd::
   File: `/etc/motd'
  Size: 17              Blocks: 16         IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 10125343    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-04-08 07:54:03.000000000  0500
Modify: 2019-03-30 19:22:13.000000000  0500
Change: 2019-03-30 19:22:13.000000000  0500
  

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

1. с первым $ awk -v RS= '/^4:/' file я не могу жестко привязать к ^4 нему переменную, и ее значение где-то помещается в переменную.

2. Я обновил ответ, чтобы показать, как использовать переменную. Это все, что вы пытаетесь сделать — распечатать запись по ее идентификатору?

3. Для второго его сопоставления ^5 с другим блоком в целом я хочу выполнить поиск в первом блоке соответствия, который ^4

4. ХОРОШО, вы хотите выполнить поиск в записи с идентификатором 4. И что потом? Распечатать запись или что-то еще? Я снова обновил свой ответ.

5. Да, мы приближаемся Access: (0644/-rw-r--r--) к переменной, поэтому для второго совпадения я могу использовать regex , потому что значение Access: изменится, но да, имя поля останется прежним