使用Perl创建另一个Perl文件

时间:2011-08-18 23:39:47

标签: perl

我有一个看起来像

的输入文件
*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代码。帮助/想法将不胜感激。如果您要发布代码片段,您可以通过并解释每个部分正在做什么吗?谢谢!

1 个答案:

答案 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;
}';