これはコード レビューなので、1 つずつ見ていきましょう。
#!/use/bin/perl
そのシバン行はおそらくタイプミスです。それはおそらく
#!/usr/bin/perl
またはwhich perl
システムに返されるものは何でも。
use strict;
use warnings;
良い。
open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
レキシカル ファイルハンドルを使用できる場合、パッケージ グローバル ファイルハンドルは必要ありません。最近では、 の 3 引数形式open
が好まれています。また、エラー メッセージには、開けなかったファイルが示されているはずです。
my $filename = '/home/user/Desktop/infile.phy';
open my $input, '<', $filename
or die "Cannot open '$filename' for reading: $!";
my @body = <FILE>;
ファイルを配列に丸呑みしています。この場合、それはまったく不要です。
my $count = 0;
my $string = '';
可能な限り最小のスコープで変数を宣言して初期化します (必要な場合)。
my $count;
変数$string
は、コード内の他の場所では使用されていません。
foreach $_(@body){
これはばかげています。for
ループ変数が指定されていない場合は $_ を使用します。代わりに字句ループ変数を指定すると、物事をまっすぐに保つのが簡単になります。
for my $line ( @body ) {
ただし、ファイルを丸呑みするべきではないと思います。
if ($_ =~ m/[X]/){
その結果、行に X が含まれている場合に一致が成功します。したがって、/X/
. ただし、「X」を含む単語はわかりません。そのためには、単語が何であるかを判断し、単語レベルでマッチングを行う必要があります。
これらすべてを念頭に置いて、次のスクリプトを検討してください。私が言葉と考えるものに関して、単純化した仮定を立てました。すべての要件を満たすために、これに基づいて構築できるはずです。
#!/usr/bin/perl
use strict;
use warnings;
my $filename = "$ENV{TEMP}/test.txt";
open my $input, '<', $filename
or die "Cannot open '$filename' for reading: $!";
my $count;
while ( my $line = <$input> ) {
my @words = grep { /X/ } split /\b/, $line;
$count += @words;
print join(', ', @words), "\n";
}
print "$count\n";
__END__
更新: 1 つ以上の X 文字を含む各行内の単語を見つけることに関心がない場合、while ループは単純化されます。
while ( <$input> ) {
$count += (my @matches = /(X)/g );
print if @matches;
}
$_ を使用して。ただし、これはおそらく非効率的です (一致した X 文字をそれぞれ保存していることを考えると)。この場合、tr
最適に機能します。
my ($count, $n);
$n = tr/X// and $count += $n and print while <$input>;