删除xml文件中两个标记之间的EOL和空格

删除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

我有很多(超过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_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 -