删除多行XML元素中的换行符

时间:2017-09-25 15:31:42

标签: perl awk sed

在Unix系统上,我有一个包含长多行字符串的输入文本文件。

我现在想要仅在两个模式(和)之间删除换行符,这两个模式可以在不同的行上。

示例输入文件:

text1 text2 <remarks> text3
text4 text5 </remarks> text6 text7 text8

上述输入文件的结果输出应为:

text1 text2 <remarks> text3 text4 text5 </remarks> text6 text7 text8

我更愿意使用sed或Perl或awk来完成这项工作。

我没有看到解决方案,因为换行符可能发生&#34;随机&#34;和文本只是一些日志消息。

这是我需要处理的输入文件的更详细的外观。它不包含根XML部分,但是对于测试我可能只是手动添加一个。也可能有许多&#34;备注&#34;部分。

Inputfile Snippet(因为它非常长),Filename是test:

<paymentTerm keyValue1="8" objectType="PAYMENTTERM" />
<paymentType keyValue1="20" objectType="PAYMENTTYPE" />
<priceList keyValue1="1" objectType="PRICELIST" />
<remarks>Zollanmeldung ab 250 €
Lager Adresse:
Hessen-Ring 456
D-64546 Mörfelden-Walldorff
eine Stunde vor Ankunft melden unter Mobile

Neu Spedition
A&amp;R Logistics Group
Storkenburgstrasse 99
D-62546 Mörfelden-Walldorf
www.asp.de</remarks>
<salesPersons>
<PERSON keyValue1="2" keyValue2="SALESEMPLOYEE" objectType="PERSON" />
</salesPersons>
<shippingType keyValue1="5" objectType="SHIPPINGTYPE" />

如上所述,我想删除模式之间的换行符&#34;备注&#34;和&#34; /备注&#34;。

我尝试了borodin建议的Perl XML Parsing:

use strict;
   use warnings 'all';

   use XML::Twig;

   use constant XML_FILE => 'test';

   my $twig = XML::Twig->new(
       twig_handlers => {
           remarks => sub { $_->set_text($_->trimmed_text) }
       }
   );

   $twig->parsefile(XML_FILE);

   $twig->print;

它有效,但在一行上打印所有内容。

2 个答案:

答案 0 :(得分:0)

使用GNU awk进行多字符RS:

$ awk -v RS='</?remarks>' -v ORS= '!(NR%2){gsub(/\n/,OFS)} {print $0 RT}' file
text1 text2 <remarks> text3 text4 text5 </remarks> text6 text7 text8

答案 1 :(得分:0)

XML可以用许多不同的方式表示相同的信息,尝试使用正则表达式处理它总是一种风险。使用适当的XML模块处理XML数据要好得多。该解决方案使用 XML::Twig

$twig对象的构造函数中,您可以指定每次在输入中遇到给定XML元素时自动调用的回调

trimmed_text方法从元素的文本中删除前导和尾随空格,并将任何内部空白序列(包括换行符)转换为单个空格。这正是你在这里要求的,所以调用set_text就是更新字符串所需的一切

要处理的文件由XML_FILE常量指定,您应该修改它以指定您自己的数据文件的路径。修改后的XML将打印到STDOUT

use strict;
use warnings 'all';
use open qw/ :std :encoding(UTF-8) /;

use XML::Twig;

use constant XML_FILE => 'remarks.xml';

my $twig = XML::Twig->new(
    keep_spaces => 1,
    twig_handlers => {
        remarks => sub { $_->set_text($_->trimmed_text) }
    }
);

$twig->parsefile(XML_FILE);

$twig->print;

输入

您的示例数据是无效的XML,因此我将其编辑为如下所示。我添加了您在评论中说过的XML声明,并添加了根元素<data>

<?xml version="1.0" encoding="UTF-8"?>
<data>
<paymentTerm keyValue1="8" objectType="PAYMENTTERM" />
<paymentType keyValue1="20" objectType="PAYMENTTYPE" />
<priceList keyValue1="1" objectType="PRICELIST" />
<remarks>Zollanmeldung ab 250 €
Lager Adresse:
Hessen-Ring 456
D-64546 Mörfelden-Walldorff
eine Stunde vor Ankunft melden unter Mobile

Neu Spedition
A&amp;R Logistics Group
Storkenburgstrasse 99
D-62546 Mörfelden-Walldorf
www.asp.de</remarks>
<salesPersons>
<PERSON keyValue1="2" keyValue2="SALESEMPLOYEE" objectType="PERSON" />
</salesPersons>
<shippingType keyValue1="5" objectType="SHIPPINGTYPE" />
</data>

输出

<?xml version="1.0" encoding="UTF-8"?>
<data>
<paymentTerm keyValue1="8" objectType="PAYMENTTERM"/>
<paymentType keyValue1="20" objectType="PAYMENTTYPE"/>
<priceList keyValue1="1" objectType="PRICELIST"/>
<remarks>Zollanmeldung ab 250 € Lager Adresse: Hessen-Ring 456 D-64546 Mörfelden-Walldorff eine Stunde vor Ankunft melden unter Mobile Neu Spedition A&amp;R Logistics Group Storkenburgstrasse 99 D-62546 Mörfelden-Walldorf www.asp.de</remarks>
<salesPersons>
<PERSON keyValue1="2" keyValue2="SALESEMPLOYEE" objectType="PERSON"/>
</salesPersons>
<shippingType keyValue1="5" objectType="SHIPPINGTYPE"/>
</data>