1

I'm trying to integrate Jenkins to grab stories from pivotal tracker which have been marked as finished if they have been included in a build (we already have integration with github on both jenkins and pivotal tracker). Using curl, I am able to grab related stories using pivotal's web api, which returns an xml with the story values. I have tested a bash regex (<current_state>(.*)<\/current_state>) on regexraptor.net, to match the node value in a string (in this case, <story><current_state>this</current_state></story>), with the goal of returning this (the desired text from the element) for assignment to a bash variable. regexraptor tells me it matches, but when I try to get output the text, it comes up blank. currently, my code to output goes like this:

$XML_STRING='<current_state>this</current_state>'
[[ $XML_STRING =~ '<current_state>(.*)<\/current_state>' ]]
echo "${BASH_REMATCH[1]}"

which outputs nothing. How can I get it to output 'this'?

Due to the constraints of the Oracle Linux distro on the server I'm using at work, I need to get this working using pure bash if possible. sed and grep are available, but I've had no luck with them- sed finds a match, but outputs the whole stream of xml rather than the single word value I want, and I just plain can't get grep working. xpath is unavailable, and xmllint has proved unworkable as well

Eddie Prislac
  • 145
  • 1
  • 10
  • 1
    Please see http://stackoverflow.com/questions/13150411/why-does-bash-rematch-not-work-for-a-quoted-regular-expression – sakurashinken Jul 30 '15 at 21:32
  • How did `xmllint` fail? I use this regularly as a general-purpose XPath query tool (`xmllint --xpath //some_query -`). Can you use something like Python that has an actual XML parser? Can you post an example of the actual XML you're trying to parse? – larsks Jul 30 '15 at 21:33
  • @larsks, many older builds of xmllint don't have the `--xpath` option (this being part of why I tend to suggest `xmlstarlet` -- certainly, it's less likely to be installed, but if it *is* installed, it's guaranteed to have the relevant functionality). But yes, using Python tends to be a good option, and would probably work for the OP. – Charles Duffy Jul 30 '15 at 21:47
  • @larsks xmllint didn't fail, it's just unavailable on the server and on the server distro's package manager, same with xmlstarlet. The post Charles offered gave me the answer (as did sakurashinken's answer). Unfortunately, due to the way bash deals with strings, I eventually decided to ditch the straight bash approach and write a command line ruby gem to deal with Jenkins/Pivotal Tracker integration instead. – Eddie Prislac Aug 06 '15 at 18:52

3 Answers3

1

Assuming that our XML looks like the XML in this question, you could extract the current_state value using xmllint like this:

$ xmllint --xpath 'string(/stories/story/current_state)' myfile.xml
accepted

If the input file contains more than one story, this will only return the first. You can select other stories by providing the appropriate index to your XPath expression:

$ xmllint --xpath 'string((/stories/story/current_state)[2])' myfile.xml 
unscheduled

If you actually have:

XML_STRING='<current_state>this</current_state>'

You can get at the value text in the middle like this:

$ echo "$XML_STRING" | cut -f2 -d'>' | cut -f1 -d'<'
this
Community
  • 1
  • 1
larsks
  • 277,717
  • 41
  • 399
  • 399
1

Bash regular expressions are written without quotes. The following code returns "this" on my mac in bash:

XML_STRING='<current_state>this</current_state>'
[[ $XML_STRING =~ \<current_state\>(.*)<\/current_state\> ]]
echo "${BASH_REMATCH[1]}"
sakurashinken
  • 3,940
  • 8
  • 34
  • 67
0

Check your file on linux in the following way:

cat -vte filename

if you see strange ^@ in every 2nd place or any other strange thing, then your file has some control character inside which make you problems. Also you may want to check/change windows end lines to linux end lines.

zolo
  • 444
  • 2
  • 6