我有一个类似于以下内容的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
<xmlns:gmi="http://sdi.eurac.edu/metadata/iso19139-2/schema/gmi" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:geonet="http://www.fao.org/geonetwork" gco:isoType="gmd:MD_Metadata">
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://server.test.it/geoserver/test_product/wms?SERVICE=WMS&TIME=2018-06-14T10:59:00Z&</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WMS-1.1.1-http-get-map</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>test_product:test_product</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>test_product:test_product</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
</csw>
我想用以下内容替换 标记的内容:
我以前在bash中使用sed
命令:
correct_url='http://server.test.it/geoserver/test_product/wms?SERVICE=WMS&version=1.1.0&request=GetMap&layers=test_product:test_product&styles=&bbox=140442.2309,3739661.3694,1330442.2309,2564661.3694&width=768&height=576&srs=EPSG:32632&format=application/openlayers&TIME=2018-06-14T10:59:00Z&'
sed -i 's/<gmd:URL>\(.*\)<\/gmd:URL>/<gmd:URL>'"${correct_url}"'<\/gmd:URL>/' xml_file.xml
它给我一个错误:
sed:-e表达式#1,字符52:`s'的未知选项
能告诉我我做错了什么吗?
更新:
使用@rubystallion的建议,我尝试转义所有特殊字符:
correct_url='http://server.test.it/geoserver/test_product/wms?SERVICE=WMS&version=1.1.0&request=GetMap&layers=test_product:test_product&styles=&bbox=140442.2309,3739661.3694,1330442.2309,2564661.3694&width=768&height=576&srs=EPSG:32632&format=application/openlayers&TIME=2018-06-14T10:59:00Z&'
correct_url_escaped="${correct_url//\//\\\/}"
correct_url_escaped="${correct_url_escaped//&/\\&}"
correct_url_escaped="${correct_url_escaped/\?/\?}"
correct_url_escaped="${correct_url_escaped/\?/\?}"
correct_url_escaped="${correct_url_escaped//\;/\;}"
correct_url_escaped="${correct_url_escaped//\=/\=}"
sed -i 's/<gmd:URL>\(.*\)<\/gmd:URL>/<gmd:URL>'"${correct_url_escaped}"'<\/gmd:URL>/' xml_file.xml
但是我仍然遇到错误:
sed:-e表达式#1,字符47:`s'的未知选项
我还缺少什么吗?
答案 0 :(得分:1)
正如评论者提到的那样,您可以编写更多可维护的脚本,并通过使用支持XML的工具来避免出错,但是让我向您展示为什么您的代码不起作用:
Bash在执行命令之前用其内容替换字符串中的变量,因此/
将被sed解析为定界符,而&
将被解析为替换字符串中的整个匹配项。如果您正确地转义了特殊字符,那么您的命令将按预期运行:
correct_url='http://server.test.it/geoserver/test_product/wms?SERVICE=WMS&version=1.1.0&request=GetMap&layers=test_product:test_product&styles=&bbox=140442.2309,3739661.3694,1330442.2309,2564661.3694&width=768&height=576&srs=EPSG:32632&format=application/openlayers&TIME=2018-06-14T10:59:00Z&'
correct_url_escaped="${correct_url//\//\\\/}"
correct_url_escaped="${correct_url_escaped//&/\\&}"
token='http://server.test.it/geoserver/test_product/wms?SERVICE=WMS&TIME=2018-06-14T10:59:00Z&'
sed -i 's/<gmd:URL>\(.*\)<\/gmd:URL>/<gmd:URL>'"${correct_url_escaped}"'<\/gmd:URL>/' xml_file.xml
此外,请确保您的命令下次按照问题中的说明进行编译。您忘记在变量周围加上引号。
答案 1 :(得分:1)
您的URL中包含特殊字符,您正在将URL替换为执行的命令。如果将echo
放在sed
命令行的前面,您会看到实际执行的内容,显然这将不是有效的sed
命令。
您需要转义该URL,或者不直接将其放入您的sed
命令中。您可以使用e标志来实现后者,该标志用执行的命令的结果替换匹配的文本。像这样:
url="http://x:y@www.a.com/foo?a=b&c=d" sed -r -i 's/(\s*)<gmd:URL>(.*)<\/gmd:URL>/echo "\1<gmd:URL>$url<\/gmd:URL>"/e' xml_file.xml
请注意,您在使用e
标志时应谨慎;因为您正在执行某些操作,所以存在潜在的安全问题。
也请注意关于使用XML编辑工具编辑XML的一般建议(在像这样的简单作业中,IMO最好使用sed
来完成它……)