我有一个“|” 分隔的文本文件。我需要组合 2 个字段,然后将其插入到同一记录中另一个字段 ($5) 给出的 xml 文件中。
awk -F "|" '{print $2$4 >> $5 }' source.txt
这样做很好,但它只是将数据附加到文件的末尾。我需要它来替换<element> blablabla </element>
位于每个 xml 中的内容。
提前致谢
如果我理解正确,您想使用从另一个文件推断的数据就地修改每个 XML 文件。例如,源数据可能如下所示:
one|fluffy|slurm|unicorns|animal.xml
two|yellow|flarn|moons|mineral.xml
three|blue|jalaroot|stars|mineral.xml
XML ......好吧,我不需要提供示例。我猜你想<element>
用 $2 和 $4 连接替换每个 XML 文件中的。如果这是不正确的,请在您的问题中澄清。
所以这里有一个选择。
#!/bin/sh
awk -F'|' '{print $5,$2$4}' source.txt | while read file data; do
case "$data" in
*#*) echo "ERROR: invalid data ('$data')" >&2 ;;
*) if [ -f "$file" ]; then
sed -ri -e "s#<element>[^>]+</element>#<element>$data</element>#" "$file"
else
echo "ERROR: no such file: '$file'" >&2
fi
;;
esac
done
这里的想法是,我们将数据作为一组 shell 变量,$file
然后$data
在 while 循环中逐步完成每个替换。替换是使用sed
“就地”(-i) 完成的。在尝试使用它之前,请阅读您的实现手册页sed
并备份您的数据。
请注意,这实际上是 POSIX 兼容的,并且不需要 bash。(虽然它在 bash 中也可以正常工作。)
条款:
未经测试,因为您没有提供任何示例 inut 或预期输出,但这应该接近您想要的:
awk -v pid="$$" '
NR==FNR {
file = $5
f2s[file,++numSubs[file]] = $2 $4
if ( !seen[file]++ )
ARGV[ARGC++] = file
next
}
{
for (i=1; i <= numSubs[FILENAME]; i++)
gsub(/<element>.*<\/element>/,"<element>" f2s[FILENAME,i] "</element>")
print > (FILENAME ".mod_" pid)
}
' source.txt
for f in *.mod_$$
do
mv -- "$f" "${f%.mod_$$}"
done
想想上面在做什么,并在你的文件副本上测试它,然后再在你的真实文件上运行它。它未经测试。
你可以试试这个bash
:
#!/bin/bash
while read line
do
arr=(${line//|/ })
sed -i.bak "s#<element>.*</element>#<element>${arr[1]}${arr[3]}</element>#g" ${arr[4]}
done < 'source.txt'
测试 :
sat:~# cat source.txt
projectName|URL|string1|string2|file.xml
projectName|URL|hello1|hello2|sample.xml
sat:~#
sat:~# cat file.xml
<element>xmlcontent</element>
sat:~#
sat:~# cat sample.xml
<element> content </element>
sat:~#
sat:~# bash sample.sh # Executing script
sat:~#
sat:~# cat file.xml
<element>URLstring2</element>
sat:~#
sat:~# cat sample.xml
<element>URLhello2</element>