понимание кода sed для обработки текста

понимание кода sed для обработки текста

Может ли кто-нибудь объяснить мне этот код sed ниже?

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Я хочу отредактировать, чтобы добавить информацию «Тип политики:». Когда я заменяю ее на «Имя политики:», все работает нормально. Однако, когда я добавляю раздел, как показано ниже, это, очевидно, не работает, потому что я пытаюсь сделать это, не понимая.

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
/Policy Type:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Также у меня есть решение для эквивалентного кода AIX ниже с того же форума, мне нужно его понять, чтобы отредактировать его и добавить тип политики.

# define constants
SPC=`echo x | tr x '\040'`
TAB=`echo x | tr x '\011'`
 NL=

# custom regex for...
s="[$SPC$TAB]";   # horizontal whitespace
S="[^$SPC$TAB]";  # non-whitespace

# POSIX compliant sed code...
sed -ne "
   /Policy Name:/!d

   s/.*:$s\{1,\}//
   h

   :1
      n
      /Active:$s*no/d
   /HW\//!b1

   :2
      s/.*$s\($S*\)$s*/\1/
      G
      s/\n/$TAB/p
      n
      /^$s*\$/d
      /Include:/d
   b2
"  yourfile

Входной файл

Policy Name:       Today

  Policy Type:       Standard
  Active:              yes
  Effective date:      01/24/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  EU         NY  Cindy
                 BU         CA  Victor
                 GU         MI  Bob
  Include:
Policy Name:       Tomorrow

  Policy Type:       Oracle
  Active:              yes
  Effective date:      01/26/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  MU         LA  Martha
                 EU         CA  Sam
  Include:
Policy Name:       Yesterday

  Policy Type:       Oracle
  Active:              no
  Effective date:      01/21/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  NV         IL  Joe

  Include:`

Желаемый результат

Cindy    Today     Standard
Victor   Today     Standard
Bob      Today     Standard
Martha   Tomorrow  Oracle
Sam      Tomorrow  Oracle

решение1

Хорошо, давайте сделаем это шаг за шагом:

sed -n '

Опция не -nвыводит sedничего, если не указано иное.

/Policy Name:/! d

Все строки, которые не содержат, Policy name:удаляются. Остальная часть скрипта обрабатывается только в следующих циклах.

s/.*:\s\+//
h

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

:1
n

Это начало цикла чтения новых строк.

/Active:\s*no/d

Строки с таким шаблоном удаляются, поэтому, очевидно, нет интереса к неактивным.

/HW\//!b1

И теперь мы переходим к циклу, :1если строка не содержитHW/

:2
s/.*\s\(\S*\)\s*/\1/

В начале следующего цикла удалите все, кроме последней последовательности непустых символов.

G
s/\n/\t/p

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

n
/^\s*$\|Include:/! b2
'

и это повторяется со следующими строками, пока мы не достигнем заданного шаблона.

Следует отметить, что это крайне непереносимый код, который не будет работать во многих sedверсиях.

Редактировать:Чтобы добавить тип политики в качестве третьего столбца, необходимо добавить эту строку в скрипт до или после проверки Active::

/Policy Type:/{s/.*:\s*//;H;}

То есть: если строка содержит указанную строку, выполнить команды между {}. Эти команды удаляют часть до :и конечных пробелов и добавляют остальную часть строки (которая должна содержать тип политики) в буфер удержания. Таким образом, буфер удержания содержит имя и тип политики, разделенные новой строкой. Поэтому, когда мы добавляем это с G, будет две новые строки для замены, поэтому команда замены должна получить флаг gдля замены всех вхождений:

s/\n/\t/gp

Скрипт AIX в основном тот же, но избегает расширений GNU для регулярных выражений. В основном используются переменные для соответствия пробелам или табуляциям, так как \tне будут работать во всех sedвариантах, а также +для "один или несколько" необходимо заменить на\{1,\}

Связанный контент