如果我搜索文件,例如。 s_webdomain 的 file.xml 我将得到:
<hostname oa_var="s_webhost">hostname</hostname>
<externURL oa_var="s_external_url">https://hostname:4450</externURL>
<directory_index oa_var="s_directory_index">index.html</directory_index>
<webentryhost oa_var="s_webentryhost">hostname.host</webentryhost>
<webentrydomain oa_var="s_webentrydomain">services.uk</webentrydomain>
<domain oa_var="s_webdomain">services.uk</domain>
<server_ip_address oa_var="s_server_ip_address"/>
<!-- Configuration files -->
<!-- SSL Variables -->
<url_protocol oa_var="s_url_protocol">http</url_protocol>
<web_ssl_directory oa_var="s_web_ssl_directory">/u03/app/ENV/gs/inst/ENV_01-bsapp01/certs</web_ssl_directory>
<local_url_protocol oa_var="s_local_url_protocol">http</local_url_protocol>
我想替换 services.uk,无论它说什么:
<domain oa_var="s_webdomain">SOME_DIFFERENT_TEXT</domain>
$ grep s_webdomain file.xml | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'
英国服务网
关于如何将 services.uk 更改为 SOME_DIFFERENT_TEXT 有什么想法吗?可能需要 sed 命令,但我不确定。
谢谢。
答案1
处理结构化文档格式的文档时,最好的处理工具是识别该格式的工具。
下面使用XML处理工具将所有具有属性的节点xmlstarlet
的值替换为 value :domain
ou_var
s_webdomain
xmlstarlet edit \
--update '//domain[@oa_var = "s_webdomain"]' \
--value "SOME_DIFFERENT_TEXT" file
或者,使用简短的选项,
xmlstarlet ed \
-u '//domain[@oa_var = "s_webdomain"]' \
-v "SOME_DIFFERENT_TEXT" file
该命令使用 XPath 查询//domain[@oa_var = "s_webdomain"]
来寻址输入文档中将更新的所有可能位置。每个匹配实体的值都会更新为(在本例中)字符串SOME_DIFFERENT_TEXT
。
Xpath模式中的首字母//
表示domain
可以找到该节点任何地方。通常,人们知道文档的结构,并且会指定指向要处理的节点的更准确的路径。
您可以在后面添加--inplace
( -L
)edit
以“就地”对文档进行更改。
要影响多个节点,例如,的webentrynode
值为:oa_var
s_webentrydomain
xmlstarlet edit \
--update '//domain[@oa_var = "s_webdomain"]' \
--value "SOME_DIFFERENT_TEXT" \
--update '//webentrydomain[@oa_var = "s_webentrydomain"]' \
--value "SOME_DIFFERENT_TEXT" file
到提炼您可以使用 的值xmlstarlet select
,如下所示:
xmlstarlet select \
--template \
--value-of '//domain[@oa_var = "s_webdomain"]' \
-nl file
或者,使用简短的选项,
xmlstarlet sel -t -v '//domain[@oa_var = "s_webdomain"]' -n file
答案2
您可以单独使用 awk:
要测试它:
awk '{sub(/s_webdomain\">services.uk/,"s_webdomain\">some_new_text"); print}' file.xml
并将其写在适当的位置:
awk -i inplace '{sub(/s_webdomain\">services.uk/,"s_webdomain\">some_new_text"); print}' file.xml
答案3
由于您的示例文档在单行上包含所有标签(以及您想要的所有匹配行),我将使用这个简单的 Perl 命令来更改该文本:
#
# perl -i.bak -p -e "s/(<.*>)(.*)(<.*>)/\${1}SOME_DIFFERENT_TEXT\${3}/ if /s_webdomain/" file.xml
#
# diff file.xml file.xml.bak
10c10
< <domain oa_var="s_webdomain">SOME_DIFFERENT_TEXT</domain>
---
> <domain oa_var="s_webdomain">services.uk</domain>
#
简单的 Perl 命令正在制作带有*.bak
扩展名的备份文件,&打印给定文本文件中的每一行,&使用正则表达式来匹配 的行s_webdomain
,然后用 , 替换中心文本SOME_DIFFERENT_TEXT
以生成输出文件。
Diff 命令通过将文本文件中的更新内容与备份文件中的原始内容进行比较来显示已更改的内容。
Perl 可能已经安装并可用。该解决方案非常快并且可以通过调整进行扩展。