一致する後続の行に基づいてファイル行から特定のフィールドを抽出する方法

一致する後続の行に基づいてファイル行から特定のフィールドを抽出する方法

職場の問題を再現しようとしています。以下のようにxmlファイルがあります。

[~]$ less -N sample.xml
  1     <SOURCE BUSINESSNAME ="" NAME ="TABLE1" FOO="ABCD"..... >
  2         <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_XYZ" />
  3         <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_ABCD" />
  4         ...
  5                 ...
  6     </SOURCE>
  7     <SOURCE BUSINESSNAME ="" NAME ="TABLE2" ....... >
  8             <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_ABCD" />
  9         <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_XYZABC" />    
 10         ...
 11                 ...
 12     </SOURCE>
 13         <SOURCE BUSINESSNAME ="" NAME ="TABLE3" .... >
 14         <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_PQR" />
 15         <SOURCEFIELD BUSINESSNAME ="" NAME ="COL_ABCD" />
 16         ...
 17                 ...
 18     </SOURCE>

今私はそれらの1つに似たフィールドの値が欲しいですNAMESOURCEFIELD NAMEXYZ

たとえば、与えられた例では、2行目をTABLE1含める必要がありますCOL_XYZTABLE29COL_XYZABC

1,2,7,9,13行を出力にインポートしてから、フィールドからgrep -B1 XYZ|grep -w SOURCE出力1,7の行を取得する方法を考えています。

Expected Output:
TABLE1
TABLE2

今まで試したこと

  • SOURCEすべての行にこれらのうちの1つ以上が含まれているため、grepを実行しても機能しません。
  • egrep -w "SOURCE|XYZ"私のニーズに合わないことをすることは、XYZABCその条件を満たさないでしょう。

目的の結果を得るために何を試すことができるかを提案できる人はいますか?使っていますLinux 2.6.18-371.el5

ベストアンサー1

hold spaceこの機能を使用すると、これを行うことができますsed

sed-n入力ラインの自動印刷を無効にするオプションで実行します。

<SOURCE含まれている行が表示されたら保存してください。属性のNAMEsedhold space

<SOURCEFIELD埋め込み行が表示されたときにXYZ印刷される内容ですhold space

#!/bin/sh

sed -n '
    /<SOURCE / {              # execute block {} on lines matching "<SOURCE "
        s/.* NAME *="//       # remove everything upto NAME attribute value
        s/".*//               # remove everything after attribute value
        h                     # copy pattern space to the hold space
    }
    /<SOURCEFIELD.*XYZ/ {     # SOURCEFIELD contains XYZ, execute {} block
        g                     # copy hold space to pattern space
        p                     # print
    }
' "$@"

おすすめ記事