如何编写一个Perl脚本来检查x列数,以便为每个返回值打印另一行中的值
我有一个CSV文件中的数据(IP地址),该文件将是第9-13列。如果其他列中没有值,那么默认情况下,它应该只打印第9列中的内容。有一个输出文件,它将打印一组值和第9列的值(如果存在值,则打印到第13列),并将其与静态值连接起来,以创建别名值。我的问题是,你如何有效地做到这一点?我有这样的代码:如何编写一个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
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";
}