脚本编写有点新。我主要是 C# 编码员,但...
我有一个XML文件,其中包含许多具有重复名称的节点,但它们的值中都有".txt">
扫描.xml
<Parent Tags>
...
<FileNameWithPath> Some/Path/That/has/file.extension.txt</FileNameWithPath>
...
</Parent Tags>
...
<Parent Tags>
...
<FileNameWithPath> Some/NewPath/That/has/Newfile.DifferentExtension.txt</FileNameWithPath>
...
</Parent Tags>
我正在尝试在 Linux 中编写一个 (bash( 脚本来删除文件中的所有".txt"子字符串。
测试出来,我有
cat IpScan.xml | sed -ne '/<FileNameWithPath>/s#s*<[^>]*>s*##gp'
但这只显示终端中标签的值。
我也尝试过这样的事情
grep -oP "<FileNameWithPath>(.*)</FileNameWithPath>" IpScan.xml | cut -d ">" -f 2 | cut -d "<" -f 1
我的想法是遍历 sed 或 grep 的每个结果并处理字符串的末尾,但我不知道如何将值写回文件。另外,我不确定 grep 或 sed 是否允许您迭代(??
我的问题是:如何打开文件,更改元素的值以删除".txt"字符串并使用更新的值保存文件?
我宁愿不必安装另一个软件包,因为我正在处理的 Linux 盒子没有网络连接。
我怎样才能
正如评论中已经提到的,使用正则表达式来操作XML文件通常是一个坏主意。但是,您可以轻松地使用 XSLT 来转换 XML 的某些部分。在更改单个值的情况下,xmlstarlet 提供了单行方法:
xmlstarlet ed -u "//Parent_Tags/FileNameWithPath" -x "normalize-space(concat(substring-before(.,'.txt'),substring-after(.,'.txt')))" input.xml
这里
ed
选项意味着值被编辑/更改-u
选项指定要更新的元素的 XPath,如for-each
循环-x
选项指定相对于-u
选项指定的上下文节点的新值。这里,.txt
之前的字符串连接到.txt
之后的字符串。normalize-space()
函数删除前导空格和尾随空格。
更新后的 XML 将输出到 STDOUT,当然,可以重定向到新的 XML 文件。
试试这个简单的sed
命令:
cat IpScan.xml | sed "s/.txt</</"
解释:
s/.txt</</
每行一次将".txt<"替换为"<">