我有一个看起来像
的输入文件*firsttitle
nameA
nameB
nameC
*secondtitle
xnameA
xnameB
xnameC
我想创建一个Perl脚本来获取此文件,并且创建另一个看起来像
的perl脚本 #!/usr/bin/perl
use strict;
use warnings;
my %tags = (
"firsttitle" => [ qw (nameA nameB nameC) ],
"secondtitle" => [ qw (xnameA xnameB xnameC) ]);
my $rx = join '|', keys %tags;
while (<>) {
s/^\s*($rx):\s*(\d+)/$1: $tags{$1}[$2]/;
print;
}
我的思维过程是我必须首先匹配打印常规perl代码(#!,use..etc。)。然后添加“my%tags =(。然后获取输入文件并查找*和这是哈希的查找并开始解析所有事情,直到下一个(*)或生命结束。如果它是另一个*然后再做。如果它是EOF然后添加“);”并结束。然后完成打印最后一个一点perl代码。帮助/想法将不胜感激。如果您要发布代码片段,您可以通过并解释每个部分正在做什么吗?谢谢!
答案 0 :(得分:1)
非常简单的脚本。首先只是解析输入文件。以*
开头的行将成为标题,并且直到下一个*
行的所有后续行都将成为值。我们将它放入数组的哈希值。
map
语句为我们提供了一个哈希键(标题)的列表,它的值与空格连接在一起。我们把它放在一个打印阵列中。打印本身是使用printf
完成的,这可能有点难以使用,因为元字符会让我们搞砸。任何要为文字的%
必须写为%%
。我还将单引号从原始引号更改为双引号。我在printf模式上使用单引号以避免意外插入变量。
替代方案 - 可能更好的方法 - 不仅仅是printf,而且只是以正常方式连接字符串。
use strict;
use warnings;
my ($title, %hash);
while (<DATA>) {
chomp;
if (/^\*(.+)$/) {
$title = $1;
} else {
push @{$hash{$title}}, $_;
}
}
my @args = ( map { $_, join(' ', @{$hash{$_}}) } keys %hash );
printf '#!/usr/bin/perl
use strict;
use warnings;
my %%tags = (
"%s" => [ qw ( %s ) ],
"%s" => [ qw ( %s ) ]);
my $rx = join "|", keys %%tags;
while (<>) {
s/^\s*($rx):\s*(\d+)/$1: $tags{$1}[$2]/;
print;
}', @args;
__DATA__
*firsttitle
nameA
nameB
nameC
*secondtitle
xnameA
xnameB
xnameC
<强>更新强>
这将使用不同的打印方法,这将更加稳定。
my @args = ( map { " '$_' => [ qw ( @{$hash{$_}} ) ],\n" } keys %hash );
print '#!/usr/bin/perl
use strict;
use warnings;
my %tags = (
', @args, '
);
my $rx = join "|", keys %tags;
while (<>) {
s/^\s*($rx):\s*(\d+)/$1: $tags{$1}[$2]/;
print;
}';