我正在尝试复制工作场所的问题。我有一个如下所示的 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>
现在我想要其中任何一个都类似于 的NAME
字段的值。SOURCEFIELD NAME
XYZ
例如,在给定的示例中,我需要TABLE1
第 2 行包含COL_XYZ
.而且我们也TABLE2
有9
COL_XYZABC
我正在考虑某种方式,将行1,2,7,9,13
作为输出,然后grep -B1 XYZ|grep -w SOURCE
在字段中仅获取1,7
输出中的行。
Expected Output:
TABLE1
TABLE2
到目前为止我尝试过的
- 执行 grep
SOURCE
不起作用,因为每一行至少有其中一个。 - 做 a
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
到第三个列表中的最后一个字段,TABLE3
打印也...