¿Cómo debería imprimir un carácter particular en el archivo después de leer el archivo?
-
13-09-2019 - |
Pregunta
Estoy leyendo un archivo mediante script de perl. Este archivo consta de cadenas con diferentes personajes y se supone que debo identificar cadenas que contienen el carácter 'X'. Quiero saber cómo debo (1) imprimir esta cadena (que contenga 'X') y (2) escribir esta cadena a otro archivo (3) contar el número de 'X' personajes de todo el archivo . El siguiente script imprime todo el archivo de nuevo. ¿Alguna sugerencia?
#!/use/bin/perl
use strict;
use warnings;
open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
my @body = <FILE>;
close (FILE);
my $count= 0;
my $string = '';
foreach $_(@body){
if ($_ =~ m/[X]/){
print "$_";
$count++;
print $count;
}
else {
print ;
}
}
exit;
Solución
Dado que se trata de revisión de código, vamos a ir uno por uno:
#!/use/bin/perl
Esa línea es tinglado más probable es un error tipográfico. Probablemente debería ser
#!/usr/bin/perl
o lo vuelve which perl
en su sistema.
use strict;
use warnings;
Buena.
open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
No hay necesidad de paquete filehandles globales cuando se puede utilizar filehandles léxicos. La forma 3-argumento de open
es preferible en estos días. Además, el mensaje de error debe indicar el fichero que no se podía abrir:
my $filename = '/home/user/Desktop/infile.phy';
open my $input, '<', $filename
or die "Cannot open '$filename' for reading: $!";
my @body = <FILE>;
Se le sorber el archivo en una matriz. Eso es completamente innecesario en este caso.
my $count = 0;
my $string = '';
declarar e inicializar (si es necesario) las variables en el más pequeño alcance posible.
my $count;
El $string
variable no se utiliza en ningún otro lugar en el código.
foreach $_(@body){
Esto es tonto. for
utiliza $ _ Si no se especifica ninguna variable de bucle. Es más fácil mantener las cosas en su lugar si se especifica una variable de bucle léxico.
for my $line ( @body ) {
Sin embargo, no creo que usted debe sorber el archivo.
if ($_ =~ m/[X]/){
Esto da lugar a una persona compatible, si la línea contiene una X. Por lo tanto, es equivalente a /X/
. Sin embargo, eso no le dirá la palabra que contenía la 'X'. Para eso, es necesario decidir qué es una palabra y hacer su juego en el nivel de palabra.
Con todo esto en mente, considere la siguiente secuencia de comandos. He hecho una suposición simplificada con respecto a lo que considero que es una palabra. Usted debe ser capaz de aprovechar este para satisfacer todos los requisitos:
#!/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__
ACTUALIZACIÓN: Si no se preocupan por encontrar las palabras dentro de cada línea que tienen uno o más caracteres X, el bucle while se simplificaría:
while ( <$input> ) {
$count += (my @matches = /(X)/g );
print if @matches;
}
utilizando $ _. Eso, sin embargo, es probablemente ineficaz (teniendo en cuenta que estamos ahorrando cada personaje X emparejado). En este caso, tr
funciona mejor:
my ($count, $n);
$n = tr/X// and $count += $n and print while <$input>;
Otros consejos
Está imprimiendo $_
en ambas ramas de su cláusula si. Deshacerse de la rama más.
Si se asume "cadena" en su pregunta es igual a "línea":
use strict;
use warnings;
@ARGV=qw(/home/user/Desktop/infile.phy);
my $count = 0;
open my $outfile, '>', 'outfile' or die $!;
while (<>) {
my $cnt = tr/X/X/;
if ($cnt) {
print;
print $outfile $_;
}
$count += $cnt;
}
close $outfile or die $!;
print $count;