I am parsing a file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<detection-run>
<wireless-network>
<SSID>
<essid>first</essid>
</SSID>
<BSSID>12:34:56:78:90</BSSID>
<wireless-client number="1">
<client-mac>A0:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="2">
<client-mac>A1:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="3">
<client-mac>A2:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="4">
<client-mac>A3:CD:EF:GH:IJ</client-mac>
</wireless-client>
</wireless-network>
<wireless-network>
<SSID>
<essid>second</essid>
</SSID>
<BSSID>98:76:54:32:10</BSSID>
<wireless-client number="1">
<client-mac>B0:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="2">
<client-mac>B1:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="3">
<client-mac>B2:CD:EF:GH:IJ</client-mac>
</wireless-client>
<wireless-client number="4">
<client-mac>B3:CD:EF:GH:IJ</client-mac>
</wireless-client>
</wireless-network>
</detection-run>
I have the following formula to extract the essid, bssid and clients:
list=$(xmlstarlet sel -T -t -m '/detection-run/wireless-network' -v 'SSID/essid' -o "|" -v 'BSSID' -o "|" -v "concat(wireless-client/client-mac, ',')" -n xmll-02.kismet.netxml)
However, that will list just one client for each network:
first|12:34:56:78:90|A0:CD:EF:GH:IJ,
second|98:76:54:32:10|B0:CD:EF:GH:IJ,
If I remove the concat portion, it will list all clients separated by a space:
list=$(xmlstarlet sel -T -t -m '/detection-run/wireless-network' -v 'SSID/essid' -o "|" -v 'BSSID' -o "|" -v 'wireless-client/client-mac' -n xmll-02.kismet.netxml)
first|12:34:56:78:90|A0:CD:EF:GH:IJ A1:CD:EF:GH:IJ A2:CD:EF:GH:IJ A3:CD:EF:GH:IJ
second|98:76:54:32:10|B0:CD:EF:GH:IJ B1:CD:EF:GH:IJ B2:CD:EF:GH:IJ B3:CD:EF:GH:IJ
How do I get the clients with a comma as a delimiter? Desired output:
first|12:34:56:78:90|A0:CD:EF:GH:IJ,A1:CD:EF:GH:IJ,A2:CD:EF:GH:IJ,A3:CD:EF:GH:IJ
second|98:76:54:32:10|B0:CD:EF:GH:IJ,B1:CD:EF:GH:IJ,B2:CD:EF:GH:IJ,B3:CD:EF:GH:IJ
EDIT: I've also tried adding -o ","
but that just adds a comma at the very end:
first|12:34:56:78:90|A0:CD:EF:GH:IJ A1:CD:EF:GH:IJ A2:CD:EF:GH:IJ A3:CD:EF:GH:IJ,
second|98:76:54:32:10|B0:CD:EF:GH:IJ B1:CD:EF:GH:IJ B2:CD:EF:GH:IJ B3:CD:EF:GH:IJ,
This is a bit tricky, as there doesn't seem to be a handy join
function (concat
just concatenates all its arguments together); you have to use nested for-each loops with multiple -m
and -b
(break) options, and a conditional to only add a comma after each but the last MAC address in the node set:
$ xmlstarlet sel -T -t -m /detection-run/wireless-network -v SSID/essid -o '|' -v BSSID -o '|' -m wireless-client -v client-mac --if 'not(position()=last())' -o , -b -b -nl input.xml
first|12:34:56:78:90|A0:CD:EF:GH:IJ,A1:CD:EF:GH:IJ,A2:CD:EF:GH:IJ,A3:CD:EF:GH:IJ
second|98:76:54:32:10|B0:CD:EF:GH:IJ,B1:CD:EF:GH:IJ,B2:CD:EF:GH:IJ,B3:CD:EF:GH:IJ