テキスト処理のための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
    '

「Policy Type:」情報を追加するように編集したいと思います。 「Policy Name:」に変更すると正常に動作しますが、以下のセクションを追加すると明らかに動作しません。理解していないまま試してみてください。 。

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多くのバージョンでは実行されません。

編集する:ポリシータイプを3番目の列として追加するには、確認の前後に次の行をスクリプトに追加する必要がありますActive:

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

つまり、行に対応する文字列が含まれている場合は、間でコマンドを実行してください{}。このコマンドは、最大:スペースと末尾のスペースを削除し、残りの行(ポリシータイプを含める必要があります)を保存バッファに追加します。したがって、保存バッファには、改行で区切られたポリシー名とタイプが含まれます。したがって、これをに追加するとG2つの改行が置き換えられるため、置換コマンドはgすべての項目を置き換えるためのフラグを取得する必要があります。

s/\n/\t/gp

AIX スクリプトは基本的に同じですが、正規表現に対する GNU 拡張を避けます。\tすべてのsedスタイルで機能するわけではなく、+「1つ以上」を次のように置き換える必要があるため、主に変数を使用してスペースまたはタブを一致させます。\{1,\}

関連情報