<filename>
我有大约 4000 个 XML 文件,我需要替换和字段的值<path>
。我需要动态替换这些字段。例如,images0001.xml
应该images0001
在两个字段内,images0002.xml
应该images0002
在两个字段内,等等。
我已经使用此命令按顺序重命名文件:
rename 's/.+/our $i; sprintf("images%04d.jpg", 1+$i++)/e' *
我还使用此命令删除了.jpg
我尝试更改的两个字段中的扩展名:
sed -i 's/.jpg//g' Annotations/*
以下是 XML 文件内容的当前状态:
<annotation>
<folder></folder>
<filename>1608644703_2.rf.fa179c1e6c47d72d668ac3d83c7f79d1</filename>
<path>1608644703_2.rf.fa179c1e6c47d72d668ac3d83c7f79d1</path>
<source>
<database>roboflow.ai</database>
</source>
<size>
<width>416</width>
<height>416</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>megot</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<occluded>0</occluded>
<bndbox>
<xmin>129</xmin>
<xmax>292</xmax>
<ymin>145</ymin>
<ymax>351</ymax>
</bndbox>
</object>
</annotation>
以下是我需要更改文件的方式:
<annotation>
<folder></folder>
<filename>images0001</filename>
<path>images0001</path>
<source>
<database>roboflow.ai</database>
</source>
<size>
<width>416</width>
<height>416</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>megot</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<occluded>0</occluded>
<bndbox>
<xmin>129</xmin>
<xmax>292</xmax>
<ymin>145</ymin>
<ymax>351</ymax>
</bndbox>
</object>
</annotation>
我正在寻找一种在命令行中执行此操作的方法,但搜索了一段时间后仍找不到解决方案!
任何帮助都将不胜感激。提前致谢!
答案1
您需要一个 XML 工具(喜欢xmlstarlet) ... 所以:
sudo snap install xmlstarlet
在一个循环中...所以:
for f in *.xml
do
xml ed -L -u "(//annotation/filename)" -v "${f/.xml/}" -u "(//annotation/path)" -v "${f/.xml/}" "$f"
done
答案2
一种方法是sed
方法是运行以下命令:
for f in *.xml; do sed "s|\(<filename>\).*\(</filename>\)|\1${f%.*}\2|; s|\(<path>\).*\(</path>\)|\1${f%.*}\2|" "$f"; done
for f in *.xml; do ... ; done
是基本 for 循环查找.xml
当前目录中的文件。找到的每个文件都存储在f
变量中。sed "s|\(<filename>\).*\(</filename>\)|\1${f%.*}\2|; s|\(<path>\).*\(</path>\)|\1${f%.*}\2|" "$f"
是针对找到的每个文件运行的命令。该命令执行两个类似的替换,一个针对字段<filename>
,另一个针对<path>
字段:
通过在文件的复制部分中使用上述命令确保其按预期工作后,-i
立即添加标志sed
以更改文件。