如何编写一个Perl脚本来检查x列数,以便为每个返回值打印另一行中的值

如何编写一个Perl脚本来检查x列数,以便为每个返回值打印另一行中的值,perl,loops,if-statement,foreach,Perl,Loops,If Statement,Foreach,我有一个CSV文件中的数据(IP地址),该文件将是第9-13列。如果其他列中没有值,那么默认情况下,它应该只打印第9列中的内容。有一个输出文件,它将打印一组值和第9列的值(如果存在值,则打印到第13列),并将其与静态值连接起来,以创建别名值。我的问题是,你如何有效地做到这一点?我有这样的代码: my $alias0= "ComponentAliases=['ComputerSystem:$columns[9]'];\n"; my $alias1= "ComponentAliases=['Comp

我有一个CSV文件中的数据(IP地址),该文件将是第9-13列。如果其他列中没有值,那么默认情况下,它应该只打印第9列中的内容。有一个输出文件,它将打印一组值和第9列的值(如果存在值,则打印到第13列),并将其与静态值连接起来,以创建别名值。我的问题是,你如何有效地做到这一点?我有这样的代码:

my $alias0= "ComponentAliases=['ComputerSystem:$columns[9]'];\n";
my $alias1= "ComponentAliases=['ComputerSystem:$columns[9]','ComputerSystem:$columns[10]'];\n";
my $alias2= "ComponentAliases=['ComputerSystem:$columns[9]','ComputerSystem:$columns[10]','ComputerSystem:$columns[11]'];\n";


        print BAROC "ComputerSystem;\n";
        if(($columns[11] != '')&&($columns[10] != '')) {  print BAROC $alias2 }
        elsif(($columns[11] == '')&&($columns[10] != '')) {  print BAROC $alias1 }
        elsif(($columns[11] == '')&&($columns[10] == '')) { print BAROC $alias0 }
这可以做我想做的事情,但是CSV文件有可能在第9-13列或9-11列中有值,等等。我很容易认为静态地编写这将是很好的,但是我希望高效地完成它,同时理解并始终应用最佳实践。我对编写Perl脚本还不熟悉,但一直被它所吸引,以解决工作中的问题。建议

这是输出,顺便说一句:

ComponentAliases=['ComputerSystem:10.1.0.225','ComputerSystem:10.200.252.77','ComputerSystem:10.100.252.77'];
一行(不太优雅,但我喜欢):

或者,如果您希望以更容易理解的方式使用相同的代码:

print(  
        "ComponentAliases=[",
        join(
            ",",
            map(    
                "'ComputerSystem:$_'",
                grep (
                        $_ ne "",
                        @columns[9-13]
                     )
               )
            ),  
        "]\n"
     );  
输出:

C:\temp> gn ComponentAliases=['ComputerSystem:10.1.0.225','ComputerSystem:10.200.252.77']; ComponentAliases=['ComputerSystem:10.1.0.225','ComputerSystem:10.200.252.77','Co mputerSystem:10.100.252.77']; C:\temp>gn 组件别名=['ComputerSystem:10.1.0.225','ComputerSystem:10.200.252.77']; 组件别名=['ComputerSystem:10.1.0.225','ComputerSystem:10.200.252.77','Co 计算机系统:10.100.252.77'] 现在高效意味着可维护。尝试保存一两条命令并不能节省您很多时间。事实上,如果编译器不能理解你在做什么,它实际上可能会使程序更加低效

重要的是可读性。去掉
$alias
之类的东西。这只会让你更难看到你的代码在做什么,你可能会在做这样的事情时产生各种各样的副作用

空白的缺乏也使得代码更难理解。一旦我重新格式化了你的代码,我立刻发现了一个错误。你做到了:

if ( ($columns[11] != '') && ($columns[10] != '') )
但是,这是一个字符串比较。您需要这样做:

if ( ( $columns[11] ne '' ) && ( $columns[10] ne '' ) ) {
或者,您可以进一步简化它:

if ( not $column[10] and not $column[11] ) {
这非常清楚您要查找的内容,并且无论列是否包含数字零、空字符串或未定义,都将起作用

此代码段使用的是您的逻辑,但我利用了以下事实:
print
不会自动在字符串末尾添加
\n
。我只是继续在这条线上继续建设:

if ( $columns[9] ) {
    print BAROC "ComputerSystem;\n";
    print BAROC "ComponentAliases=['ComputerSystem:$columns[9]'";

    if ( $columns[10] ) {
         print BAROC ",ComputerSystem:$columns[10]";
    }
    if ( $columns[11] )  {
        print BAROC ",ComputerSystem:$columns[11]";
    }
    print BAROC "];\n";
}
您提到,如果第9列到第13列中包含数据,则可能需要第9列到第13列。为什么不使用循环呢

if ( $#columns >= 9 ) {    #There are at least nine columns
    print BAROC "ComputerSystem;\n";
    print BAROC "ComponentAliases=[ComputerSystem:$columns[9]";

    for my $column ( (10..$#columns) ) {
       last if not $column[$column];
       print BAROC ",ComputerSystem:$columns[$columns];
    }
    print BAROC "];\n";
}
如果给我更多的时间,我相信我可以把逻辑整理得更清楚一点。但是,无论有9列、10列、11列还是43列包含数据,这都会起作用

if ( $columns[9] ) {
    print BAROC "ComputerSystem;\n";
    print BAROC "ComponentAliases=['ComputerSystem:$columns[9]'";

    if ( $columns[10] ) {
         print BAROC ",ComputerSystem:$columns[10]";
    }
    if ( $columns[11] )  {
        print BAROC ",ComputerSystem:$columns[11]";
    }
    print BAROC "];\n";
}
if ( $#columns >= 9 ) {    #There are at least nine columns
    print BAROC "ComputerSystem;\n";
    print BAROC "ComponentAliases=[ComputerSystem:$columns[9]";

    for my $column ( (10..$#columns) ) {
       last if not $column[$column];
       print BAROC ",ComputerSystem:$columns[$columns];
    }
    print BAROC "];\n";
}