Saltar al contenido

¿Cómo reemplazo líneas en medio de un archivo con Perl?

Intenta entender el código correctamente antes de utilizarlo a tu trabajo si ttienes algo que aportar puedes dejarlo en la sección de comentarios.

Solución:

Creo que esta es la respuesta de preguntas frecuentes que más he vuelto a publicar en Stackoverflow. El perlfaq5 tiene la respuesta a ¿Cómo cambio, elimino o inserto una línea en un archivo, o agrego al principio de un archivo?.

Olvídate de las cosas del modo agregar. Eso sólo va a hacer tu vida más difícil.


La idea básica de insertar, cambiar o eliminar una línea de un archivo de texto implica leer e imprimir el archivo hasta el punto en el que desea realizar el cambio, realizar el cambio y luego leer e imprimir el resto del archivo. Perl no proporciona acceso aleatorio a las líneas (especialmente porque el separador de entrada de registro, $/es mutable), aunque módulos como Tie::File pueden falsificarlo.

Un programa Perl para realizar estas tareas toma la forma básica de abrir un archivo, imprimir sus líneas y luego cerrar el archivo:

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

while( <$in> )
    
    print $out $_;
    

close $out;

Dentro de ese formulario básico, agregue las partes que necesita para insertar, cambiar o eliminar líneas.

Para anteponer líneas al principio, imprima esas líneas antes de ingresar al ciclo que imprime las líneas existentes.

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the topn"; # <--- HERE'S THE MAGIC

while( <$in> )
    
    print $out $_;
    

close $out;

Para cambiar las líneas existentes, inserte el código para modificar las líneas dentro del ciclo while. En este caso, el código busca todas las versiones en minúsculas de “perl” y las pone en mayúsculas. Esto sucede para cada línea, ¡así que asegúrese de que se supone que debe hacer eso en cada línea!

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the topn";

while( <$in> )
    
    s/b(perl)b/Perl/g;
    print $out $_;
    

close $out;

Para cambiar solo una línea en particular, el número de línea de entrada, $., es útil. Primero lea e imprima las líneas hasta la que desea cambiar. A continuación, lea la única línea que desea cambiar, cámbiela e imprímala. Después de eso, lea el resto de las líneas e imprímalas:

while( <$in> )   # print the lines before the change
    
    print $out $_;
    last if $. == 4; # line number before change
    

my $line = <$in>;
$line =~ s/b(perl)b/Perl/g;
print $out $line;

while( <$in> )   # print the rest of the lines
    
    print $out $_;
    

Para saltar líneas, use los controles de bucle. El siguiente en este ejemplo salta las líneas de comentarios y el último detiene todo el procesamiento una vez que encuentra __END__ o __DATA__.

while( <$in> )
    
    next if /^s+#/;             # skip comment lines
    last if /^__(END

Haga lo mismo para eliminar una línea en particular utilizando next para omitir las líneas que no desea que aparezcan en la salida. Este ejemplo salta cada quinta línea:

while( <$in> )
    
    next unless $. % 5;
    print $out $_;
    

Si, por alguna extraña razón, realmente desea ver el archivo completo de una vez en lugar de procesarlo línea por línea, puede sorberlo (¡siempre que pueda caber todo en la memoria!):

open my $in,  '<',  $file      or die "Can't read old file: $!"
open my $out, '>', "$file.new" or die "Can't write new file: $!";

my @lines = do  local $/; <$in> ; # slurp!

    # do your magic here

print $out @lines;

Los módulos como File::Slurp y Tie::File también pueden ayudar con eso. Sin embargo, si puede, evite leer todo el archivo de una sola vez. Perl no devolverá esa memoria al sistema operativo hasta que finalice el proceso.

También puede utilizar las frases ingeniosas de Perl para modificar un archivo en el lugar. Lo siguiente cambia todo ‘Fred’ para ‘Barney’ en enArchivo.txt, sobrescribiendo el archivo con el nuevo contenido. Con el -p switch, Perl envuelve un bucle while alrededor del código que especifique con -ey -i activa la edición en el lugar. La línea actual está en $_. Con -pPerl imprime automáticamente el valor de $_ al final del bucle. Consulte perlrun para obtener más detalles.

perl -pi -e 's/Fred/Barney/' inFile.txt

Para hacer una copia de seguridad de inFile.txt, dé -i una extensión de archivo para agregar:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt

Para cambiar solo la quinta línea, puede agregar una verificación de prueba $.el número de línea de entrada, solo realice la operación cuando pase la prueba:

perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt

Para agregar líneas antes de una determinada línea, puede agregar una línea (¡o líneas!) antes de que Perl imprima $_:

perl -pi -e 'print "Put before third linen" if $. == 3' inFile.txt

Incluso puede agregar una línea al principio de un archivo, ya que la línea actual se imprime al final del bucle:

perl -pi -e 'print "Put before first linen" if $. == 1' inFile.txt

Para insertar una línea después de una que ya está en el archivo, use el -n cambiar. es como -p excepto que no se imprime $_ al final del bucle, así que tienes que hacerlo tú mismo. En este caso, imprima $_ primero, luego imprima la línea que desea agregar.

perl -ni -e 'print; print "Put after fifth linen" if $. == 5' inFile.txt

Para eliminar líneas, imprima solo las que desee.

perl -ni -e 'print unless /d/' inFile.txt

    ... or ...

perl -pi -e 'next unless /d/' inFile.txt

Puedes hacer esto con Tie::File. (Tenga en cuenta que tendrá que volver a escribir todo el archivo para reemplazar las líneas iniciales, pero Tie::File le ocultará los detalles).

Una buena expresión de Perl es leer y escribir la entrada y salida estándar. Puede canalizar y redirigir según sea necesario. A través del operador <> (un ajuste a la línea de lectura), Perl abrirá los archivos que pase como argumento en la línea de comando.

Para responder a su pregunta, algunas líneas de código (lo más limpias posible):

#!/usr/bin/env perl
use strict; use warnings;

while (<>) 
  if ($. == 2) 
    print "new data", "n";
    next;
  
  if ($. == 3) 
    print "very new data", "n";
    next;
  
  print;


print "more data", "n"; 

Entonces llámelo de esta manera: perl yourscript.pl archivo de entrada > archivo de salida

Si desea abrir los archivos usted mismo (aquí simplemente omitimos las líneas no deseadas):

my open $in_fh, '<', $inputfile
  or die "Can't open file $inputfile: $!";

my open $out_fh, '>', $outputfile
  or die "Can't open file $output: $!";

while (my $line = <$in_fh>) 
  next if ( $. == 2 or $. == 3 or $. == 4 );
  print $out_fh $line;

print $out_fh "...whatevern";

Puedes secundar nuestro trabajo escribiendo un comentario y dejando una puntuación te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *