職場の問題を再現しようとしています。以下のように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つに似たフィールドの値が欲しいですNAME
。SOURCEFIELD NAME
XYZ
たとえば、与えられた例では、2行目をTABLE1
含める必要がありますCOL_XYZ
。TABLE2
9
COL_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
含まれている行が表示されたら保存してください。値属性のNAME
。sed
hold 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
}
' "$@"
答え2
sed -netP -eH -e'# Hold every line and test for s///uccess' \
-e'\|<[^F]*[ >]|!d' -e'# if < then F before [ >]: delete' \
-ex -e'\|_XYZ[^_]*>|!d' -e'# first exchange buffers; if !XYZ: delete' \
-e's|[^"]*|\n&\n|4' -e'# wrap 4th no quotes series in newlines' \
-e'D;:P' -eP -e'# Delete up to first newline, :Print if true'
TABLE1
TABLE2
...追加するときXYZ
3番目のリストの最後のフィールドとして、TABLE3
印刷図...