XML이 기록되는 로그 파일이 있습니다. 모든 노드에 특정 문자열이 있는 모든 XML을 검색하고 추출해야 합니다.
예를 들어 로그 파일에는 검색 매개변수가 포함된 여러 XML이 있습니다.
randomlogentry1
randomlogentry2
Printing XML:<CreateDataABC>
<Tag1>searchparam</Tag1>
</CreateDataABC>
randomlogentry3
randomlogentry4
randomlogentry5
Printing XML: <DataCreatedABC>
<TagA>otherparam</TagA>
<TagB>searchparam</TagB>
<TagC>otherparam</TagC>
</DataCreatedABC>
randomlogentry6
randomlogentry7
예상되는 출력은 콘솔에 인쇄되거나 별도의 파일에 작성된 두 개의 XML입니다.
XML1:
<CreateDataABC>
<Tag1>searchparam</Tag1>
</CreateDataABC>
XML2:
<DataCreatedABC>
<TagA>otherparam</TagA>
<TagB>searchparam</TagB>
<TagC>otherparam</TagC>
</DataCreatedABC>
XML에서 "searchparam"의 위치는 고정되지 않으며 유일한 상수는 "ABC" 문자열과 "searchparam"입니다.
sed를 사용하여 두 줄 번호 사이의 내용을 추출하고 싶습니다. 다음을 시도했습니다.
- 검색 매개변수를 검색하고 줄 번호를 식별합니다.
- ABC의 다음 발생을 찾아 줄 번호를 얻습니다.
특정 행에서 이전에 발생한 ABC를 찾을 수 없는 것 같습니다.
전에 이런 일을 해본 사람이 있나요?
편집: 예제 로그 형식 및 예상 출력이 업데이트되었습니다.
답변1
이 시도:
Max=`grep -c "^Printing" file.xml`
for count in `seq 1 $Max`
do
sed -nr '/Printing/H;//,/ABC/G;s/\n(\n[^\n]*){'$count'}$//p' file.xml | sed 's/Printing XML://' > $count.xml
done
답변2
이것이 내가 쓴 것이지만, 이 작업을 수행하는 더 짧고 우아한 방법이 있다고 확신합니다.
searchstring=searchparam
filename=test.log
pattern1=ABC
linenums=($(grep -n "${searchstring}" ${filename} | awk -F":" '{print $1}'))
len=${#linenums[@]}
for (( i=0; i<${len}; i++ ));
do
currentline=${linenums[$i]}
relativeendlinearray=($(tail -n +${currentline} ${filename} | grep -n "${pattern1}" | awk -F":" '{print $1}'))
actualendline=$(($currentline+${relativeendlinearray[0]}-1))
index=$currentline
while [ $index -ne 0 ]
do
found=`sed "${index}q;d" ${filename} | grep "${pattern1}"`
if [ -n "$found" ]; then
actualstartline=$index
break;
fi
index=$[$index-1]
done
if [ -n "$found" ]; then
echo ""
else
echo "Log break detected, content across multiple files"
fi
echo "Start Line" ${actualstartline}
echo "Current Line" ${currentline}
echo "End Line" ${actualendline}
sed -n "${actualstartline},${actualendline}p" ${filename}
done