I have an XML file with multiple lines like below.
<sandbox>false</sandbox>
<serverUrl>https://salesforce.com/services/Soap/u/37.0/</serverUrl>
<sessionId>00D4100000087K9!AQMAQJElzjgvA01eaCo</sessionId>
<userId>00541000000JOzJAAW</userId>
<userInfo>
I am trying to use sed on Linux to get a value between the two sessionId tags.
sed -n '/<sessionId>.*$/{s/<sessionId>.*<\/sessionId>/\1/;p}' LoginResponse.xml
But it is throwing the below error. Any suggestions please...
sed: -e expression #1, char 50: invalid reference \1 on `s' command's RHS
答案 0 :(得分:3)
根本不要使用sed
; XML不是常规语言,因此regular expressions are categorically not powerful enough to parse it correctly。您当前的代码无法将有关sessionId标记的注释与真实的sessionId标记区分开来;无法识别元素编码;无法处理您的代码中出现的意外属性;等
相反,请使用:
xmlstarlet sel -t -m '//sessionId' -v . -n < LoginResponse.xml
...或者,如果你没有XMLStarlet,你可以使用XSLTProc(在现代UNIX系统上几乎普遍可用的开箱即用)。如果您将以下内容另存为extract-session-id.xslt
:
<?xml version="1.0"?>
<!-- this was generated with:
-- xmlstarlet sel -C -t -m '//sessionId' -v . -n
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//sessionId">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="."/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...然后您可以运行xsltproc extract-session-id.xslt LoginResponse.xml
来获取输出。
sed
事物也就是说,关于你的sed
错误:你需要通过-r
来启用ERE语法:
# requires GNU sed for -r
sed -r -n -e '/<sessionId>.*$/{s/<sessionId>(.*)<\/sessionId>/\1/;p}'
或者,使用MacOS BSD sed,还需要进行一些其他调整:
# -E, not -r, on MacOS BSD sed; semicolon between "p", "}" needed.
sed -E -n '/<sessionId>.*$/ { s/<sessionId>(.*)<\/sessionId>/\1/; p; }'
如果你的会话ID曾经包含元素后面的字符,那么这会很糟糕 - &
s看起来像&
,依此类推;因此,使用适当的XML解析器是更安全的选择。 (同样,如果内容曾经发生变化<sessionid type="foo">...</sessionid>
,或者发生任何其他变化的情况。)
答案 1 :(得分:0)
对于工作的参考,你必须告诉说使用圆括号引用什么,你没有。