Hi there,

I have the xml file (HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml) that contains data between tags that i want to extract.

The sample data from the xml file that i have etracted is like below :

<record record_no = "62" error_code="100">D20|000000063|56604960 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579536|1348579538|3|0|IDD|Flat Rate
<record record_no = "63" error_code="100">D20|000000064|7A257C4E 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579572|1348579620|48|0|IDD|Flat Rate

<record record_no = "64" error_code="100">D20|000000065|5661A576 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579556|1348579559|3|0|IDD|Flat Rate
but from those data i extracted, i wanted to create the outpurt like :

record no: 62, error code: 100, D20|000000063|56604960 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579536|1348579538|3|0|IDD|Flat Rate

record no: 63, error code: 100, D20|000000064|7A257C4E 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579572|1348579620|48|0|IDD|Flat Rate

record no: 64, error code: 100, D20|000000065|5661A576 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579556|1348579559|3|0|IDD|Flat Rate

what i have done so far is here :

#!/bin/sh
tmp=grep.log
output=output.log

file=`cat HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml|grep "<record"|cat >> $tmp`

while read $file
 do
   ------not sure,what to put here?------ | >> cat $output
 done 

-------------------------------------------------------------------------------------

so, any help guys? im confused right now T____T
thanks~~

Dani AI

Generated

This thread demonstrates the common trap of treating XML like plain text. ’s sed suggestions and ’s later sed-based fix work for very simple, single-line records, but the original sed parse error usually points to shell-quoting or sed-dialect differences (GNU vs BSD/Solaris) or to use of regex features not supported by the installed sed. For reliable, maintainable output (attributes + element text) an XML-aware tool is safer than fragile regexes.

A compact, robust option is xmlstarlet (purpose-built for XPath extraction). This prints each record on one line, pulling the two attributes and the element text while normalizing whitespace:

xmlstarlet sel -t -m '//record' -v "concat('record no: ',@record_no,', error code: ',@error_code,', ',normalize-space(.))" -n HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml > output.log

If xmlstarlet is not available, a short Python script using ElementTree is portable and clear (handles multi-line content and entity decoding):

#!/usr/bin/env python3
import xml.etree.ElementTree as ET
for r in ET.parse('HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml').iterfind('.//record'):
    text = (r.text or '').strip()
    print(f"record no: {r.get('record_no')}, error code: {r.get('error_code')}, {text}")

Troubleshooting notes: if sed must be used, check the sed implementation and quoting (some sed versions lack alternation or extended-regex support). Avoid echo|cat and unnecessary command-substitution; use direct redirection. If records can span lines or contain nested markup, prefer the XML methods above to avoid data loss or mis-parsing.

Recommended Answers

All 9 Replies

or the output could be like below if it make this any simpler :

record_no = "62" error_code="100" D20|000000063|56604960 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579536|1348579538|3|0|IDD|Flat Rate

record_no = "63" error_code="100" D20|000000064|7A257C4E 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579572|1348579620|48|0|IDD|Flat Rate

record_no = "64" error_code="100" D20|000000065|5661A576 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579556|1348579559|3|0|IDD|Flat Rate

hi,

simply

sed -n '/^<record/{s/"\|<//g; s/>\|_/ /g;p}' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml

you should seriously re-read your course!

HI Watael,

yeah, i just learned shell script via the internet and very new to this..
anyways, i wrote the line like this :

file="sed -n '/^<record/{s/"\|<//g; s/>\|_/ /g;p}' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml"

test_out=echo "$file" |cat > $msg

but get the error below :

sed: Function /^<record/{s/"\|<//g; s/>\|_/ /g;p} cannot be parsed.

--------------------------------------------------------------------

what problem could it be? thankss for your help..

file="sed -n '/^<record/{s/"\|<//g; s/>\|_/ /g;p}' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml"
test_out=echo "$file" |cat > $msg

all this is useless, and does not what you expect it should do in your opinion (that is command substitution).

command substitution occurs between $( and ), but, again, it's useless here.

why are you doing so?

simply

msg="/path/to/anotherFile"
sed -n '/^<record/{s/"\|<//g; s/>\|_/ /g;p}' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml > "$msg"

hi watael,

thanks for your help..but still the same errors occur after i follow exactly like what you said :

#!/bin/sh

msg=/var/Batch/UEL_Data/uel/test/msg.log
sed -n '/^<record/{s/"\|<//g; s/>\|_/ /g;p}' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml > "$msg"

i still got this :

sed: Function /^<record/{s/"\|<//g; s/>\|_/ /g;p} cannot be parsed.

or maybe even to make it simpler, i decide to just make the ouput become just like below :
____________________________________________________________________________________________________________________________
record_no = "62" error_code="100">D20|000000063|56604960 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579536|1348579538|3|0|IDD|Flat Rate

record_no = "63" error_code="100">D20|000000064|7A257C4E 071411E2 BC9D24B6 FDB63DEA|6088342010|0166662635|DEFAULT|1348579572|1348579620|48|0|IDD|Flat Rate
____________________________________________________________________________________________________________________________

this means, now i just have to figure out how to remove "<record" from the beginning of each line.

i cannot use sed, so i dont know why and dont know what else i could try to do this..I have tried using grep, but thats only working if i just have one line, and not multiple lines like this case.

any help?thanks..

try to remove the semicolon between g and p

what system are you on?

Hi watael,

I finally figured out whats wrong and the correct way to do that,

actually when we are using sed, i noticed that we need to echo out the data first before we could modify them.So i ended up writing the code like this which turns out to be working correctly like what i wanted :

#!/bin/sh

error=`sed 's/<record//g' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml`

save_error=`echo "$error"|cat > $msg`

anyways, thanks for your helps and suggestions :)

we need to echo out the data first before we could modify them

that's quite strange.
what system are you on?

save_error, and cat are useless

#!/bin/sh

error=$(sed 's/<record//g' HSBB_voice_20120925_0000000182.cdr.bc_lerr.xml)
echo "$error" > "$msg"
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.