テキスト処理のための 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これは移植性が非常に低く、多くのバージョンでは動作しないコードであることに注意してください。

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

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

つまり、行に上記の文字列が含まれている場合は、 の間のコマンドを実行します{}。これらのコマンドは、 と末尾の空白までの部分を削除し:、行の残りの部分 (ポリシー タイプが含まれているはずの部分) をホールド バッファーに追加します。したがって、ホールド バッファーには、改行で区切られたポリシー名とタイプが含まれます。これを で追加するとG、置換する改行が 2 つあるため、置換コマンドはgすべての出現箇所を置換するためのフラグを取得する必要があります。

s/\n/\t/gp

AIX スクリプトは基本的に同じですが、正規表現の GNU 拡張を避けています。主に、空白やタブに一致する変数を使用しますが、これは\tすべてのフレーバーで機能するわけではありませんsed。また、+「1 つ以上」は次のように置き換える必要があります。\{1,\}

関連情報