<属性> <名称>mapred.tasktracker.map.tasks.maximum</名称> <值>2</值> <description>将运行的最大地图任务数 同时由任务跟踪器执行。 </描述> </属性> <属性> <名称>mapred.tasktracker.reduce.tasks.maximum</名称> <值>2</值> <description>将运行的最大reduce任务数 同时由任务跟踪器执行。 </描述> </属性>
我想通过我的脚本输出的值来改变(mapred.tasktracker.map.tasks.maximum 值),并且不改变超出它的其他值(reduce 任务的最大数量),我该怎么做呢?!
答案1
首先,你的 XML 文件似乎不完整,它缺少类似
<?xml version="1.0"?>
<top>
...
</top>
如果您添加它,您可以使用它xmlstarlet
来修改 XML 文件。
xmlstarlet ed -P -u "/top/property/name[text()='mapred.tasktracker.map.tasks.maximum']/../value" -v 4 nameofxmlfile
有关这方面的信息您可以了解man xmlstarlet
一下xmlstarlet ed --help
。
xmlstarlet 将在编辑模式下运行 ( ed
),它将加载文件nameofxmlfile
,保留空白节点 ( -P
),并将节点的值更改为 4 ( -v 4
)。要修改的节点由 XPath 标识"/top/property/name[text()='mapred.tasktracker.map.tasks.maximum']/../value"
。这将从左到右阅读:从顶层开始 ( /
),进入top
节点,进入每个property
子节点,进入name
子节点,仅过滤具有给定文本的名称 ( [text()='mapred.tasktracker.map.tasks.maximum']
),向上一个节点(..
,再次返回属性),然后向下进入value
子节点。
结果将打印到 stdout。如果您希望 xmlstarlet 修改文件,请-L
在 后添加-P
。
答案2
1. 使用 XML 解析器
如果要操作 XML,则应使用专门为此目的设计的工具。(Unix 中没有内置此类工具。)Stack Exchange 上已多次讨论过此问题:
- 堆栈溢出:
- Unix 和 Linux:
XMLStarlet(Werner Henze 提到) 似乎被广泛推荐。
2. 然而……
...如果您的数据表现良好(例如,每行有一对匹配的标签;没有看起来像标签但实际上不是标签的字符串;等等...),您可能能够使用标准 Unix 命令来执行此操作。
2.1 awk
awk '
/<name>mapred.tasktracker.map.tasks.maximum<\/name>/ { inzone=1 }
inzone && /<value>.*<\/value>/ { sub(/<value>.*<\/value>/, "<value>4</value>"); inzone=0 }
/<\/property>/ { inzone=0 }
1
'
- 识别
mapred.tasktracker.map.tasks.maximum
字符串后,设置inzone
标志以表明我们要更改接下来value
看到的字符串。 - 如果我们发现
value
我们处于区域内(inzone
),则用新值替换它并将inzone
标志清零。 - 如果我们看到 的结尾
property
,请清除标志,因为我们不再处于mapred.tasktracker.map.tasks.maximum
数据中。
2.2 sed
sed '/<name>mapred.tasktracker.map.tasks.maximum<\/name>/ {
: loop
n
s/<value>.*<\/value>/<value>4<\/value>/
t
/<\/property>/b
b loop
}'
- 识别
mapred.tasktracker.map.tasks.maximum
字符串后,输入{…}
命令块。 - 以标签(
loop
)开始该块,这样我们就可以多次执行以下命令(直到找到value
)。 - 转到下一行。
- 尝试替换该值。
- 如果替代成功,则跳至循环结束。
- 如果我们看到 的结尾
property
,则分支到循环的末尾,因为我们不再位于数据中mapred.tasktracker.map.tasks.maximum
。 - 否则,分支到循环的开始处,并重复上述操作。