我这里有一个小情况,我希望一些Linux魔术师可以帮助我。我有一个文件夹/assets
,其中有.jpg
和.xml
文件-一吨。
原始xml结构:
<annotation>
<folder></folder>
<filename>Pro_jpeg.rf.77216510eeb475f923d5bb3bdb22ee11.jpg</filename>
<path>Pro_jpeg.rf.77216510eeb475f923d5bb3bdb22ee11.jpg</path>
<source>
<database>roboflow.ai</database>
</source>
<size>
<width>416</width>
<height>416</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>cheese</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>53</xmin>
<xmax>371</xmax>
<ymin>224</ymin>
<ymax>391</ymax>
</bndbox>
</object>
</annotation>
如果你看一下,你可以看到在<bndbox>
标记中,我定义了以下参数:xmin, xmax, ymin and ymax
-在该序列中。它是错误的,我想用以下序列更新所有我的.xml文件:xmin, ymin, xmax, ymax
。因此文件将如下所示:
<annotation>
<folder></folder>
<filename>Pro_jpeg.rf.77216510eeb475f923d5bb3bdb22ee11.jpg</filename>
<path>Pro_jpeg.rf.77216510eeb475f923d5bb3bdb22ee11.jpg</path>
<source>
<database>roboflow.ai</database>
</source>
<size>
<width>416</width>
<height>416</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>cheese</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>53</xmin>
<ymin>224</ymin>
<xmax>371</xmax>
<ymax>391</ymax>
</bndbox>
</object>
</annotation>
有什么想法可以做到这一点吗?提前感谢!
编辑(我目前拥有的):所以我打开终端,导航到文件夹:cd desktop并调用此块。所有文件都位于desktop/cheese 1文件夹中:
for file in cheese1/*.xml; do
xmlstarlet edit -L --delete "//bndbox/xmax" --insert "//bndbox/ymin" --to "//bndbox/xmin" \
--insert "//bndbox/xmax" --to "//bndbox/ymax" \
"$file"
done
什么都没有发生,所以不确定是语法错误,是逻辑错误还是两者兼而有之。
4条答案
按热度按时间ddarikpa1#
Sed解决方案,它假设所有输入数据的格式都与示例中相同,并且错误的序列总是按
xmin > xmax > ymin > ymax
排序:使用
sed -i
就地编辑您的文件,如果输出满足您的要求。它的工作方式非常简单,在
<bndbox>...</bndbox>
行之间,我们保存<xmax>
行并删除它,然后当我们遇到<ymin>
行时,我们将之前保存的<xmax>
行粘贴到<ymin>
行之后。zqry0prt2#
假设:
一个
awk
的想法:这产生:
一旦输出被验证正确,有几个选项可用于更新输入文件:
GNU awk
,我们可以添加inplace
选项,例如:awk -i inplace 'flag ... <see_rest_of_script_above> ...' file.xml
否则...mv tmpfile file.xml
lyr7nygr3#
通过
xmlstarlet
使用xslt转换:XSLT:
通过
xmlstarlet
在循环中使用bash globbing进行XSLT转换:转换前的目录内容:
转换后的目录:
更新的XML示例:
fbcarpbf4#
使用
xmlstarlet edit
将一个XML元素移动到指定的位置,如下所示:1.插入一个新的空节点作为目标,
-i
用于前面的兄弟节点,-a
用于后面的兄弟节点1.将源的内容复制到新节点
1.复制后删除源
N
引用$B/xmax
可替换为annotation/object/bndbox/xmax
、$N/preceding-sibling::*[1]
或等效值-x '$N/node() | $N/@*'
在子轴和属性轴上创建源节点的深层副本(使用联合)(因为ymin
实际上没有任何属性,所以可以剥离| $N/@*
)-L
(又名--inplace
)更新所有已处理XML文件的时间戳,即使输出与输入相同--var
定义了一个命名变量,而$prev
变量引用了由最新的-s
、-i
或-a
选项创建的节点,这些选项都定义或重新定义了它(有关--var
和$prev
的示例,请参见xmlstarlet.txt
)。