如何通过从命令行传递参数在Perl中应用IN子句

问题描述:

我是Perl的新手,并试图使用XML::Twig模块在XML文件上应用过滤条件。如何通过从命令行传递参数在Perl中应用IN子句

以下是我的代码:

#!/usr/bin/perl 
use strict; 
use warnings; 

use XML::Twig; 

my $SOURCEFILE  = $ARGV[0]; 
my $FILELOCATIONIN = $ARGV[1]; 

my $twig = new XML::Twig(twig_handlers => { 'STOCKEXT/STOCK' => \&STOCK }); 

$twig->parsefile($FILELOCATIONIN.'/'.$SOURCEFILE.'.xml'); 

$twig->set_pretty_print('indented'); 

$twig->print_to_file($FILELOCATIONIN.'/'.$SOURCEFILE.'out.xml'); 

sub TRADE { 
    my ($twig, $STOCK) = @_; 
    foreach my $c ($STOCK) 
     { 
     $c->delete($STOCK) 
     unless 
     $c->att('origin') eq "HIGH_TRADE" 

     ; 
    } 
} 

以下是我的XML:

<STOCKEXT> 
    <STOCK origin = "HIGH_TRADE"/> 
    <STOCK origin = "HIGH_TRADE"/> 
    <STOCK origin = "HIGH_TRADE"/> 
    <STOCK origin = "LOW_TRADE"/> 
    <STOCK origin = "LOW_TRADE"/> 
    <STOCK origin = "AVERAGE_TRADE"/> 
</STOCKEXT> 

滤波输出XML:

<STOCKEXT> 
    <STOCK origin = "HIGH_TRADE"/> 
    <STOCK origin = "HIGH_TRADE"/> 
    <STOCK origin = "HIGH_TRADE"/> 
</STOCKEXT> 

现在我坚持,我想通过逗号在命令行中分隔参数,以便HIGH_TRADE以及AVERAGE_TRADE变为legi timate STOCK

可以看出,在我当前的代码中,我传递了两个参数。但我想传递三个参数,第三个应该是以逗号分隔格式的过滤条件。

因此,我期待我的代码要调用

perl stock_filter.pl file_name.xml /opt/XML HIGH_TRADE,AVERAGE_TRADE 

第三个参数将被分割,并核对每个STOCK元素的origin属性来声明它是合法的。

这将有助于将来改变过滤条件。过滤条件的任何加法或减法都不会改变代码。

做到这一点的一种方法是存储您希望保留在散列中的值。

my @origins_to_keep= split /,/, $ARGV[2]; 
my %keep= map { $_ => 1 } @origins_to_keep; 

使用它在处理程序:

在脚本的顶端创建哈希

$c->delete($STOCK) unless $keep{$c->att('origin')} 
+0

全局符号 “%保持” 需要明确的包name..error它抛出......不明白为什么.. – 2015-02-23 08:45:48

+0

明白了...而不是我的$ keep = map {$ _ => 1} origins_to_keep,它应该是我的%keep = map {$ _ => 1} @origins_to_keep,因为它是哈希...谢谢... – 2015-02-23 10:03:58

+1

oops,在回答中修复了 – mirod 2015-02-23 12:35:04

最为明显,我的解决方法是使用any函数从List::Util模块。

以下是您自己的代码版本,其中包含一些其他修改。最重要的是,我使用File::Spec::Functions模块中的catfile函数更安全地组合路径和文件名。

use strict; 
use warnings; 
use 5.014; # For non-destructive substitution 

use XML::Twig; 
use File::Spec::Functions 'catfile'; 
use List::Util 'any'; 

my ($source_file, $file_location, $stock_origins) = @ARGV; 

my $twig = XML::Twig->new(
    twig_handlers => { 'STOCKEXT/STOCK' => \&stock_handler }, 
    pretty_print => 'indented', 
); 

my $full_input = catfile($file_location, $source_file); 
my @stock_origins = split /,/, $stock_origins; 
my $full_output = $full_input =~ s/(?=\.[^.]+\z)/_out/r; 

$twig->parsefile($full_input); 
$twig->print_to_file($full_output); 

sub stock_handler { 
    my ($twig, $stock) = @_; 
    my $origin = $stock->att('origin'); 

    $stock->delete unless any { $origin eq $_ } @stock_origins; 
} 

输出

<STOCKEXT> 
    <STOCK origin="HIGH_TRADE"/> 
    <STOCK origin="HIGH_TRADE"/> 
    <STOCK origin="HIGH_TRADE"/> 
    <STOCK origin="AVERAGE_TRADE"/> 
</STOCKEXT> 
+0

“any “不是由List :: Util模块导出....这是我正面临的错误......任何想法......先生.. – 2015-02-23 09:06:03

+0

您需要更新您的'List :: Util'副本 – Borodin 2015-02-23 09:38:00

+1

Yeeah明白了!!!!!! – 2015-02-23 10:04:55