删除xml文件中两个标记之间的EOL和空格
我有很多(超过50个)xml文件,其中一些行(每个文件超过30/40行)格式不正确: 例如:删除xml文件中两个标记之间的EOL和空格,xml,bash,formatting,Xml,Bash,Formatting,我有很多(超过50个)xml文件,其中一些行(每个文件超过30/40行)格式不正确: 例如: <TAG1> <TAG_TO_FORMAT> a_random_string </TAG_TO_FORMAT> <AN_OTHER_TAG_TO_FORMAT> an_other_random_string </AN_OTHER_TAG_TO_FOR
<TAG1>
<TAG_TO_FORMAT>
a_random_string
</TAG_TO_FORMAT>
<AN_OTHER_TAG_TO_FORMAT>
an_other_random_string
</AN_OTHER_TAG_TO_FORMAT>
<OTHER_TAG>pifpafpouf</OTHER_TAG>
</TAG1>
随机字符串
一个\u其他\u随机\u字符串
pifpafpouf
应转化为:
<TAG1>
<TAG_TO_FORMAT>a_random_string</TAG_TO_FORMAT>
<AN_OTHER_TAG_TO_FORMAT>an_other_random_string</AN_OTHER_TAG_TO_FORMAT>
<OTHER_TAG>pifpafpouf</OTHER_TAG>
</TAG1>
随机字符串
一个\u其他\u随机\u字符串
pifpafpouf
无论
之前的新行是否仍然存在,我的关键问题是每个模式:random\u string
必须在一行上(random\u string不包含EOL)
我在bash中找不到任何允许我执行此操作的工具,那么如何在bash中执行此操作呢?(或者用python,但我更喜欢bash)。我建议用Perl来完成这类任务
#!/usr/bin/env perl
use strict;
use warnings;
my $text = join "", <>;
$text =~ s/>\s+([^\s].*?[^\s])\s+<\//>$2<\//;
print "$text";
#/usr/bin/env perl
严格使用;
使用警告;
我的$text=加入“”;
$text=~s/>\s+([^\s].?[^\s])\s+$2 output.xml
您可以在sed中完成:
x='TAG_TO_FORMAT'
sed -e '/<'"$x"'>/{:next;/<\/'"$x"'>/!{N;bnext;};s/\n//g;s/>\s*/>/;s/\S\s*</</;}'
x='TAG\u TO\u格式'
sed-e'/{:next;//!{N;bnext;};s/\N//g;s/>\s*/>/;s/\s\s*有一些命令行工具,如xmllint和tidy,可以这样使用:
my.pl < input.xml > output.xml
tidy -xml -iq somefile.xml
理论上,xmllint也可以做到这一点,但xmllint在OS X上的工作方式与我描述的不同(目前没有一个Linux实例可供测试):
Tidy做了一个合理的工作,另一个选择是使用xslt转换调用normalize-space()
或者在管道中
run_some_command | xsltproc normalize-space.xsl - | xmllint --format -
xmllint--noblanks并不一定将我想要的所有空格字符都表示为“可忽略”。它在技术上几乎肯定是正确的,但不是我想要的。awk在这里可能非常有用,绝对值得谷歌搜索。我能得到的最接近的字符是awk'/$/{printf$0”“;next;}1'
。我建议使用tidy
,因为我不知道TAG_to_格式的值,它可以有不同的格式错误的标记。下次你应该在你的问题中提到类似的约束。我不知道TAG_to_格式的值,它可以有不同的格式错误的标记,只是在关闭和打开一个文件之间的文本匹配然后用方括号括起来。请参阅更新的answer.tidy工作正常,xmllint在我的Linux实例(centOs6.3)上不工作。我只是在命令tidy中添加了-wrap 0选项,因为我有一些行(string
)这超过了64个字符。当您删除--format
并执行xmllint时,noblanks somefile.xml
。xmlint
在我的Ubuntu 15.10上完成了这项工作。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="@*|node()|/">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="@kname"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(text())"/>
</xsl:template>
xsltproc normalize-space.xsl file.xml
run_some_command | xsltproc normalize-space.xsl - | xmllint --format -