Considering following input, which is some kind of a "list" of devices from nodes, I want to get the IP addresses, but only from devices named 'router.' (not router1., nor gw. or others):

gw.bec2,,HNA: router.bec2,4|router.bec2,,online,0
gw1.ros78,,HNA: router.ros78,4|gw1test.ros78,,HNA: router.ros78,8|gw34.ros78,,HNA: router.ros78,4|router.ros78,,online,0
router.jed99,,online,0|router1.jed99,,online,0|router2.jed99,,erstellt: 09.10.14,9

optimal would be to somehow extract only those values from the example:

long story:

I am parsing an XML file to get nodename and nodeid. Now further I need the IP of the device named exactly 'router'. The XML file gives an attribute 'devices' for each node, which is a list of devices of the node, an example of three nodes can be seen above. That "list" seperates devices by pipe "|" and its attributes by comma ",".

So far I was able to get the nodename and nodeid but am now struggling to get the IP.

xpath -q -e 'concat(/nodes/node[@name="bec2"]/@name,"-",/nodes/node[@name="bec2"]/@nodeid,"-",/nodes/node[@name="bec2"]/@devices)' map.xml
# output:
# bec2-169-gw.bec2,,HNA: router.bec2,4|router.bec2,,online,0
# but needed output would be something like:
# bec2-169-

I tried something like this, but the order of devices is different per node, so selecting the field by number seems not appropriate:

xpath -q -e 'concat(/nodes/node[@name="bec2"]/@name,"|",/nodes/node[@name="bec2"]/@nodeid,"|",/nodes/node[@name="bec2"]/@devices)' map.xml | cut -d"|" -f 1,2,4
xpath -q -e 'concat(/nodes/node[@name="ros78"]/@name,"|",/nodes/node[@name="ros78"]/@nodeid,"|",/nodes/node[@name="ros78"]/@devices)' map.xml | cut -d"|" -f 1,2,4
# output:
# bec2|169|router.bec2,,online,0
# ros78|1054|gw1test.ros78,,HNA: router.ros78,8

My idea would be to split by pipe, to get each device, then search for string 'router.', then take found device and split it by comma to get second attribute.

But I don't know if and how it is possible to split by character and select results not by number but by searching a string?


(I could not add tag xpath as it needs 300 reputation)

  • Could you maybe post the XML document rather than the operations that you perform on the XML document? That way, someone may be able to give you an XPATH query that would extract the IP addresses that you want, directly from the XML rather than from a digested form of he data. – Kusalananda Jun 11 at 6:31

Using grep and cut:

<file grep -Eo 'router\.[^,]*,[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d, -f2
  • grep for the router\. part followed by any number of non-comma characters [^,]*, followed by comma , and ip address
  • then remove the first part using cut and separator -d, leaving the second field -f2

Assume | is your data separator.

grep -Po '\brouter\.[^|]+?(\d{1,3}\.){3}\d{1,3}' data  | grep -Po '(?<=,).*'
  • first grep result:
  • second grep result:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.