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.kismetxml)
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.kismetxml)
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,
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.kismetxml)
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.kismetxml)
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,
Share
Improve this question
edited Mar 17 at 6:39
Ulrich Eckhardt
17.5k5 gold badges31 silver badges60 bronze badges
asked Mar 14 at 3:35
Temp AccountTemp Account
3281 gold badge2 silver badges8 bronze badges
1
|
2 Answers
Reset to default 2This 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
This should be also work:
-o "" → Ensure the last MAC doesn’t get an extra comma.
-n → Move to a new line for the next network.
xmlstarlet sel -T -t -m '/detection-run/wireless-network' \
-v 'SSID/essid' -o "|" \
-v 'BSSID' -o "|" \
-m 'wireless-client' -v 'client-mac' -o "," -b \
-o "" -n xmll-02.kismetxml
or with the string-join():
xmlstarlet sel -T -t -m '/detection-run/wireless-network' \ -v 'SSID/essid' -o "|" -v 'BSSID' -o "|" \ -v "string-join(wireless-client/client-mac, ',')" -n xmll-02.kismetxml
concat
combines all its arguments, doesn't join a node set; see developer.mozilla./en-US/docs/Web/XML/XPath/Reference/… – Shawn Commented Mar 14 at 4:11