大家好我是perl的初学者,我遇到了一些问题,因为我想把我的字符串从AA开始到\ in到一个数组并想要保存它。 txt文件中有大约2000-3000个字符串,从相同的首字母开始,即AA到/我这样做是因为如果我错了,请纠正我。
AA c0001
BB afsfjgfjgjgjflffbg
CC table
DD hhhfsegsksgk
EB jksgksjs
\
AA e0002
BB rejwkghewhgsejkhrj
CC chair
DD egrhjrhojohkhkhrkfs
VB rkgjehkrkhkh;r
\
$flag = 0
while ($line = <ifh>)
{
if ( $line = m//\/g)
{
$flag = 1;
}
while ( $flag != 0)
{
for ($i = 0; $i <= 10000; $i++)
{ # Missing brace added by editor
$array[$i] = $line;
} # Missing brace added by editor
}
} # Missing close brace added by editor; position guessed!
print $ofh, $line;
close $ofh;
答案 0 :(得分:8)
欢迎使用StackOverflow。
您的代码存在多个问题。首先,请发布可编辑的Perl;我不得不添加三个大括号来给它最小的编译机会,我不得不猜测其中一个去了哪一个(而且我应该在print
语句的另一侧有一个中等的可能性。它)。
接下来,专家们:
use warnings;
use strict;
在他们的脚本的顶部,因为他们知道如果他们不这样做,他们会错过。作为一个学习者,你必须这样做;它会阻止你犯错误。
有了这些,您必须在使用它们时声明变量。
接下来,请记住缩进代码。这样做可以更容易理解。 Perl在最好的时候可能是不可理解的;不要让它变得更难。 (你可以决定你喜欢大括号的位置 - 这对讨论是开放的,虽然选择你喜欢的风格并坚持下去比较简单,忽略任何讨论,因为讨论可能会毫无结果。)
数据中的EB与VB是否显着?很难猜到。
目前还不清楚你究竟是在追求什么。可能是你在一个条目数组之后,一个用于文件中的每个块(其中块在仅包含反斜杠的行结束),并且数组中的每个条目都是由前两个字母键入的哈希值该行的(或第一个单词),该行的其余部分为该值。这是一个非常复杂的结构,可能超出了你在学习Perl的过程中预期会使用的结构。
您有while ($line = <ifh>)
行。如果您以旧式方式打开文件,这在Perl中无效,但这不是您应该学习的方式。您没有显示输出文件句柄是如何打开的,但在尝试打印时会使用现代表示法。但是,那里也有一个错误:
print $ofh, $line; # Print two values to standard output
print $ofh $line; # Print one value to $ofh
您需要仔细研究代码,并考虑循环逻辑。我确定你所拥有的不是你所需要的。但是,我不确定你需要什么。
来自评论:
我想将从AA到
\
的每条记录标记为记录0,直到记录n,并希望将其保存在包含所有记录号的新文件中。
然后你可能只需要:
#!/usr/bin/env perl
use strict;
use warnings;
my $recnum = 0;
while (<>)
{
chomp;
if (m/^\\$/)
{
print "$_\n";
$recnum++;
}
else
{
print "$recnum $_\n";
}
}
这将从命令行中指定的文件(或标准输入,如果没有)中读取,并将标记的输出写入标准输出。除了“记录结束”标记行之外,它的前缀是记录号和空格。选择输出格式和文件处理以满足您的需求。你可能会说chomp
会适得其反;你可以在没有它的情况下编写程序代码。
在提问者没有明确指示的情况下发展。
这是一种可能的读取数据的方法,但它使用适度高级的Perl(哈希引用等)。 Data::Dumper
模块对于打印出Perl数据结构也很有用(请参阅:perldoc Data::Dumper
)。
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @data;
my $hashref = { };
my $nrecs = 0;
while (<>)
{
chomp;
if (m/^\\$/)
{
# End of group - save to data array and start new hash
$data[$nrecs++] = $hashref;
$hashref = { };
}
else
{
m/^([A-Z]+)\s+(.*)$/;
$hashref->{$1} = $2;
}
}
foreach my $i (0..$nrecs-1)
{
print "Record $i:\n";
foreach my $key (sort keys $data[$i])
{
print " $key = $data[$i]->{$key}\n";
}
}
print Data::Dumper->Dump([ \@data ], [ '@data' ]);
示例输出,例如输入:
Record 0:
AA = c0001
BB = afsfjgfjgjgjflffbg
CC = table
DD = hhhfsegsksgk
EB = jksgksjs
Record 1:
AA = e0002
BB = rejwkghewhgsejkhrj
CC = chair
DD = egrhjrhojohkhkhrkfs
VB = rkgjehkrkhkh;r
$@data = [
{
'EB' => 'jksgksjs',
'CC' => 'table',
'AA' => 'c0001',
'BB' => 'afsfjgfjgjgjflffbg',
'DD' => 'hhhfsegsksgk'
},
{
'CC' => 'chair',
'AA' => 'e0002',
'VB' => 'rkgjehkrkhkh;r',
'BB' => 'rejwkghewhgsejkhrj',
'DD' => 'egrhjrhojohkhkhrkfs'
}
];
请注意,除了记录号之外,此数据结构未针对搜索进行优化。如果您需要以其他方式搜索数据,则需要以不同方式对其进行组织。 (并且不要将这些代码作为你的答案而不理解它 - 它是微妙的。它也没有错误检查;当心有缺陷的数据。)
答案 1 :(得分:2)
这不可能是正确的。我可以看到你的while循环有两个主要问题。
进入以下循环后
while ( $flag != 0)
{
...
}
你永远不会爆发,因为你找不到断线就不会重置旗帜。如有必要,您必须解析输入并退出循环。
第二,你从来没有读过这个循环中的任何输入,因此一遍又一遍地处理相同的$line
。
您不应该将循环放在代码中,而是可以使用以下模式(伪代码)
if flag != 0
append item to array
else
save array to file
start with new array
end
答案 2 :(得分:2)
我相信你想要的是在\
拆分文件内容,虽然它不太清楚。
要实现此目的,您可以通过设置输入记录分隔符将文件粘贴到变量中,然后拆分内容。
要了解与文件处理程序相关的Perl特殊变量,请阅读perlvar
#!perl
use strict;
use warnings;
my $content;
{
open my $fh, '<', 'test.txt';
local $/; # slurp mode
$content = <$fh>;
close $fh;
}
my @blocks = split /\\/, $content;
确保本地化修改Perl的特殊变量,以免干扰程序的不同部分。
如果您想保留分隔符,可以将$/
直接设置为\并跳过拆分。
#!perl
use strict;
use warnings;
my @blocks;
{
open my $fh, '<', 'test.txt';
local $/ = '\\'; # seperate at \
@blocks = <$fh>;
close $fh;
}
答案 3 :(得分:1)
这是一种将数据读入数组的方法。正如我在评论中所说,将这些数据“保存”到文件是没有意义的,除非你改变它。因为如果我要将下面的@data
数组打印到文件中,它会像输入文件一样完全。
所以,在我们给你一个关于如何做的答案之前,你需要告诉我们你想要完成的是什么。
此脚本遵循以下规则(确切地说):
$line
$line
\
,停止连接
行并将$line
保存到@data
。这些匹配的正则表达式非常宽松,因为它们也匹配AAARGH
和\bonkers
。如果你需要它们更严格,你可以尝试/^\\$/
和/^AA$/
,但是你需要注意行的开头和结尾的空格。所以也许/^\s*\\\s*$/
和/^\s*AA\s*$/
代替。
代码:
use warnings;
use strict;
my $line="";
my @data;
while (<DATA>) {
if (/^AA/) {
$line = $_;
while (<DATA>) {
$line .= $_;
last if /^\\/;
}
}
push @data, $line;
}
use Data::Dumper;
print Dumper \@data;
__DATA__
AA c0001
BB afsfjgfjgjgjflffbg
CC table
DD hhhfsegsksgk
EB jksgksjs
\
AA e0002
BB rejwkghewhgsejkhrj
CC chair
DD egrhjrhojohkhkhrkfs
VB rkgjehkrkhkh;r
\