эквивалентный код sed для AIX

Кто-нибудь может дать мне эквивалентный код для нижеприведенного кода sed? Он отлично работает в Linux Однако я получаю ошибку "sed: 0602-403 /Policy Name:/! d не является распознанной функцией" при запуске на AIX.

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
    '

Входной файл

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
0
06.06.2017, 12:02
2 ответа

Это переработанный код для включения имен политик, а также для приведения его в соответствие с POSIX. Обратите внимание, что все ссылки на \s -> [[:space:]], \S -> [^[:space:]] , \+ -> \{1,\}

PS: Не знаю, что делает строка /HW\//!b1 в ориг. код, сидящий там как приложение, которое может оказаться болезненным, если не быть осторожным.

TAB=`printf '\t'`; # literal TAB char will be used below
sed -ne '
   /^Policy Name:/!d

   s/.*:[[:space:]]\{1,\}//;h

   :1
      n
      /Active:[[:space:]]\{1,\}no/d
      /^[[:space:]]*Policy Type:/{
         s/.*:[[:space:]]\{1,\}//;H
      }
   \|^[[:space:]]*LC/CY/Custmr:|!b1

   :2
      s/.*[[:space:]]\([^[:space:]]*\)[[:space:]]*/\1/
      G;s/\n/'"${TAB}"'/pg;n
      /^[[:space:]]*$/d
      /Include:/d
   b2
' yourpolicyfile

Результаты

Cindy   Today   Standard
Victor  Today   Standard
Bob     Today   Standard
Martha  Tomorrow        Oracle
Sam     Tomorrow        Oracle
0
28.01.2020, 02:33
# 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

Комментарии

  • AIX sed не понимает \s \S как пробельные или непробельные символы.
  • POSIX sed не понимает пробел перед командой sed, в вашем случае /.../! д.
  • Также обратите внимание, что \+ не является POSIX. Правильное выражение для этого: \{1,\} или $s$s*, где $s — атомы регулярного выражения.
  • \t также не является POSIX. Здесь пригодится переменная оболочки $TAB.
  • \| для операции ИЛИ в sed является не-POSIX. Мы должны разбить его на части и перестроить логику.

Предупреждение

  1. Возможно, ваша оболочка пытается расширить историю вокруг символа !d. В этом случае используйте одинарные кавычки вокруг этой области. В остальном двойные кавычки необходимы для того, чтобы переменные $s, $S, $TAB можно было расширить.
  2. Регулярное выражение $S БУДЕТ соответствовать \n, как показано на рисунке. Но этот сценарий никогда не возникает в вашем коде, так как вы меняете NL -> TAB.
2
28.01.2020, 02:33

Теги

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