bash - 使用生成的字符串作为命令的 sed
问题描述
我有一个 xml,其中包含 3 个其他 xml 文件的路径。我们将文件称为 main、cfg、config 和 engine。来自 main.xml 的相关摘录:
<cfgfile>path/to/cfg/cfg.xml</cfgfile>
<enginefile>path/to/engine/engine.xml</enginefile>
<configfile>path/to/config/config.xml</configfile>
我想用 pwd 替换“path/to/x”(并将 main、cfg、config 和 engine 复制到 pwd)。对于cfg,我可以这样做:
sed 's%path/to/cfg/cfg.xml%"$(pwd)"/cfg.xml' source_path/main.xml > ./main.xml
为了让它“更简单”,我试图通过一个循环来做到这一点:
S="";
for ele in "cfg" "engine" "config"; do
S=$S's%<'"$ele"'>.*</'"$ele"'>%<'"$ele"'>'"$(pwd)"'</'"$ele"'>;';
done;
echo $S
我在其他 3 个文件中有类似的更改。因此,与其键入所有命令,不如使用循环。我知道我可以更轻松地使用 awk 或 python,但只需使用 sed 尝试一下。所以问题是我可以使用生成的变量 S 作为 sed oneliner 中的命令(而不将其重定向到文件),例如: sed 'use $S' source_path/a.xml
解决方案
@Cyrus 评论绝对正确。XML 比您想象的要多。
如果您了解 XPath,您可以轻松地xmlstarlet
与sed
.
for a in cfgfile enginefile configfile
do
temppath="$( xmlstarlet sel -t -m "//${a}" -v "normalize-space(node())" main.xml | sed -e "s#path/to/[^\/]\+#$( pwd )#g" )"
tempxml="$( xmlstarlet ed -u "//${a}" -v "${temppath}" main.xml )" && echo "${tempxml}" > main.xml
done
这确保您不会破坏 XML 结构。不幸的是,XPath 中没有 regex-match-replace 函数(据我所知)。
推荐阅读
- python - 如何从公会 discord.py 中的所有成员中删除多个角色
- python-3.x - 对于灰度到 rgb 问题,我应该使用哪个损失函数?
- sharepoint - SharePoint WebPart 上下文菜单进入 div(请参见图片)
- ios - 传入的 GameCenter 邀请不包含任何玩家
- excel - 如何使用后缀(k、m、g、uF、H 等)对电子值进行排序?
- memory-management - 分页和非连续内存分配
- python-3.x - 我如何计算一行中有多少个 1 或 0?
- python - 无法限制内存
- r - 我应该使用什么方法/模块对文本进行分类/分类?
- laravel - Laravel 和图像验证