我有一个这样的字符串:
LOADID##49945-19-0-3540FAA-16995-16995%%ANAME##NWADVE15%%AID##51826%%AGNAME##ADDLEXPR%%AGID##49945%%HNAME##teranetcmoduat.teraner.com%%LOADDATE##07-12-16%%LOADTIME##02-04-53.end
我必须提取参数的值:
LOADID, ANAME, AID, AGNAME, AGID, HNAME, LOADDATE, LOADTIME
...并将其写入文本文件。输出格式为:
49945-19-0-3540FAA-16995-16995|NWADVE15|51826|ADDLEXPR|49945|teranetcmoduat.teraner.com|07-12-16|02-04-53
答案 0 :(得分:1)
my %rec = split /##|%%/, $s, -1;
-OR -
my %rec = map { split /##/, $_, 2 } split /%%/, $s;
后者的优点是它支持没有值的键,以及包含##
的值。简单地说,它更可靠。
my @headers = qw( LOADID ANAME AID AGNAME AGID HNAME LOADDATE LOADTIME );
say join "|", @rec{@headers};
-OR -
use Text::CSV_XS qw( );
my @headers = qw( LOADID ANAME AID AGNAME AGID HNAME LOADDATE LOADTIME );
my $csv = Text::CSV_XS->new({
auto_diag => 2,
binary => 1,
sep_char => '|',
});
$csv->say(\*STDOUT, [ @rec{@headers} ]);
后者生成以管道分隔的CSV文件,因此它可以支持包含|
的值,但可以使用CSV引用。
答案 1 :(得分:-1)
根据您的输入,您可以搜索
^LOADID##([^%]+)%%ANAME##([^%]+)%%AID##([^%]+)%%AGNAME##([^%]+)%%AGID##([^%]+)%%HNAME##([^%]+)%%LOADDATE##([^%]+)%%LOADTIME##([^%]+).end$
并替换为
\1|\2|\3|\4|\5|\6|\7|\8
有:
+
替换*
。)和查看实际操作:RegEx101。
但字符串拆分可能更有效。
请评论是否需要调整/进一步详细说明。
答案 2 :(得分:-1)
只需一个带有2个正则表达式替换的简单Perl脚本即可 (用Perl 5测试)
$ cat input.txt
LOADID##49945-19-0-3540FAA-16995-16995%%ANAME##NWADVE15%%AID##51826%%AGNAME##ADDLEXPR%%AGID##49945%%HNAME##teranetcmoduat.teraner.com%%LOADDATE##07-12-16%%LOADTIME##02-04-53.end
$ echo 's/(.*?)##(.*?)(?:%%|\.end$|$)/$2|/g;s/\|$//' > pipeitup.pl
$ perl -p pipeitup.pl input.txt > result.txt
$ cat result.txt
49945-19-0-3540FAA-16995-16995|NWADVE15|51826|ADDLEXPR|49945|teranetcmoduat.teraner.com|07-12-16|02-04-53
添加第二个正则表达式替换s/\|$//
以删除管道末尾
因此,如果最终的管道不会给您带来麻烦,那么您可以将其高尔夫球化为只有第一个正则表达式替换s/(.*?)##(.*?)(?:%%|\.end$|$)/$2|/g
。
顺便说一句,只需稍作修改即可打印带有字段名称的标题。 (因为这些名称在第一个正则表达式的捕获组1中)
$ head -n1 input.txt |perl -p -e 's/(.*?)##(.*?)(?:%%|\.end$|$)/$1|/g;s/\|$//' >header.txt