我需要创建一个文本文件(aptest.s),我可以用来读入另一个程序。我正在使用Perl,因为我有一个很大的列表可供使用。我的代码如下(它没有给出所需的输出 - 显示在代码和实际输出之后)。任何帮助将不胜感激。
#!/usr/bin/perl -w
chdir("D://projects//SW Model ODME");
@link = ("319-116264||319-118664","320-116380||320-116846","321-119118||321-119119","322-115298||322-119087");
@link1 = ("116264-319||118664-319","116380-320||116846-320","119118-321||119119-321","115298-322||119087-322");
open (FSAS, ">>aptest.s");
foreach $link (@link) {
foreach $link1 (@link1){
print FSAS "other code \n";
print FSAS "PATHLOAD SELECTLINK=(Link=".$link."), VOL[2]=MW[1] \n";
print FSAS "PATHLOAD SELECTLINK=(Link=".$link1."), VOL[3]=MW[2] \n";
print FSAS "other code \n";
}
}
实际输出:
other output
PATHLOAD SELECTLINK=(Link=319-116264||319-118664), VOL[2]=MW[1]
PATHLOAD SELECTLINK=(Link=116264-319||118664-319), VOL[3]=MW[2]
other output
other output
PATHLOAD SELECTLINK=(Link=**319-116264||319-118664**), VOL[2]=MW[1]
PATHLOAD SELECTLINK=(Link=**116380-320||116846-320**), VOL[3]=MW[2]
other output
所需输出
other output
PATHLOAD SELECTLINK=(Link=319-116264||319-118664), VOL[2]=MW[1]
PATHLOAD SELECTLINK=(Link=116264-319||118664-319), VOL[3]=MW[2]
other output
other output
PATHLOAD SELECTLINK=(Link=**320-116380||320-116846**), VOL[2]=MW[1]
PATHLOAD SELECTLINK=(Link=**116380-320||116846-320**), VOL[3]=MW[2]
other output
答案 0 :(得分:21)
请参阅List::MoreUtils中的 each_array
:
#!/usr/bin/perl
use strict;
use warnings;
use List::MoreUtils qw( each_array );
my @x = qw( A B C D E F );
my @y = (10, 11, 12, 13, 14, 15);
my $it = each_array( @x, @y );
while ( my ($x, $y) = $it->() ) {
print "$x = $y\n";
}
__END__
答案 1 :(得分:4)
我认为你正在尝试创建四个单独的块,link
数组中的每个元素都与{{1}中的相应元素相关联数组?
但是,您实际上正在输出 16个块,link2
和link
的每个组合一个。
而是尝试:
link1
答案 2 :(得分:2)
阅读你的问题,很难说出你真正想知道的是什么。我相信Sinan Unur是正确的,并且您希望在两个阵列上同时迭代。正如他所说,List :: MoreUtils提供了非常方便的each_array()
函数。
通过索引迭代一个或多个数组也很简单。
您可以生成索引列表,以便与普通for循环一起使用。这使用$#
来获取数组中最后一个值的索引。
for ( 0..$#array ) { ... }
或者您可以使用C风格的循环来生成索引。这使用了在标量上下文中计算的数组返回元素数的事实。
for ( my $i=0; $i<@array; $i++ ) { ... }
也可以使用$#
:
for ( my $i=0; $i<=$#array; $i++ ) { ... }
阅读完代码后,很明显您不熟悉Perl's quoting operators。有效地使用它们可以使脚本更容易编写和阅读。
友好地请允许我整理你的剧本:
#!/usr/bin/perl
# Always:
use strict;
use warnings;
#my $TARGET_DIR = 'D://projects//SW Model ODME';
my $TARGET_DIR = '.';
my $TARGET_FILE = 'aptest.s';
# Using qw() makes long lists of
# literals easier to type and read.
# Consider finding better names than link and link1.
# Something that describes the relationship between
# the two arrays.
my @link = qw(
319-116264||319-118664
320-116380||320-116846
321-119118||321-119119
322-115298||322-119087
);
my @link1 = qw(
116264-319||118664-319
116380-320||116846-320
119118-321||119119-321
115298-322||119087-322
);
# check the results of chdir.
chdir($TARGET_DIR)
or die "Unable to enter $TARGET_DIR - $!\n";
# Use a lexical filehandle.
# Use 3 arg open
# Check the results of open - you need to know if it fails.
open (my $fsas, '>>', $TARGET_FILE)
or die "Unable to open $TARGET_FILE - $!\n";
# Verify that the link arrays are both sized appropriately.
die "Link arrays are not the same size."
unless @link == @link1;
# Loop over the indexes of the array.
# For very (very) large arrays it is
# more efficient to use a C-style for loop:
# for( my $i = 0; $i < @link; $i++ ) {
foreach my $i (0..$#link) {
my $link = $link[$i];
my $link1 = $link1[$i];
print $fsas Get_Link_Text($link, $link1);
}
# Broke out your formatting code into a routine for readability.
# Used a heredoc to make the formatting easier to read.
# Also, took advantage of variable interpolation in the heredoc to further
# improve readability.
# I preserved the whitespace at the end of lines, is it really necessary?
sub Get_Link_Text {
my $link = shift;
my $link1 = shift;
return <<"--END_TEXT--";
RUN PGM=HWYLOAD
MATI=daily_trucks.MAT
NETI=FAF_Network_V11.net
NETO=MiamiDade.NET
PARAMETERS MAXITERS=1, GAP=0.001, COMBINE=EQUI
FUNCTION {
TC[1] = T0*(1+0.15*(V/100)^(4))}
FUNCTION V = (VOL[1])
PHASE=ILOOP
PATHLOAD PATH=TIME, MW[1]=MI.1.1, SELECTLINK=(Link=$link), VOL[2]=MW[1]
PATHLOAD PATH=TIME, MW[2]=MI.1.1, SELECTLINK=(Link=$link1), VOL[3]=MW[2]
ENDPHASE
ENDRUN
--END_TEXT--
}
答案 3 :(得分:0)
在重现错误的同时,您是否可以减小代码和示例数据的大小?我无法立即看到实际和预期产出之间的差异。
有时,找到导致问题的最小代码和数据集会使解决方案显而易见。
仔细一点,只有一位输出代码可变:
print FSAS "PATHLOAD PATH=TIME, MW[1]=MI.1.1, SELECTLINK=(Link=".$link."), VOL[2]=MW[1] \n";
print FSAS "PATHLOAD PATH=TIME, MW[2]=MI.1.1, SELECTLINK=(Link=".$link1."), VOL[3]=MW[2] \n";
你的错误可能就在那里。