직장 문제를 재현하려고 합니다. 아래와 같이 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
예를 들어, 주어진 예에서는 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
모든 줄에 이들 중 하나 이상이 포함되어 있으므로 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
세 번째 목록의 마지막 필드로,TABLE3
인쇄도...