2010-02-23 13 views
10

La gente sigue haciendo esta pregunta y sigo respondiéndola con la misma respuesta de perlfaq5. Ahora es algo a lo que podemos apuntar en Stackoverflow.¿Cómo cambio, elimino o inserto una línea en un archivo o añado al comienzo de un archivo en Perl?

+0

¿Cuál es el punto de volver a publicar 'perlfaqN' aquí? ¿No puedes simplemente dar un enlace a 'perfaq5' http://perldoc.perl.org/perlfaq5.html#How-do-I-change%2c-delete%2c-or-insert-a-line-in- a-file% 2c-or-append-to-the-beginning-of-a-file% 3f a los solicitantes? – codeholic

+2

Siempre odio los enlaces. Los sitios web se vuelven obsoletos, las URL cambian, etc. Creo que Stackoverflow debe capturar información para que siempre la tenga. Recuerde, este es un proyecto a largo plazo en el que la respuesta debería ser tan buena en tres años como lo es ahora. Un enlace no garantiza eso. Recuerde que www.perldoc.com solía ser el sitio preferido para documentos hasta que desaparecía. Eso podría pasarle a cualquier sitio. –

+0

Además, vea el tema del meta donde le pregunté sobre la importación de todo el perlfaq: http://meta.stackexchange.com/questions/24244/can-we-import-the-perlfaq-into-stackoverflow –

Respuesta

13

De perlfaq5:

La idea básica de inserción, cambio o supresión de una línea de un archivo de texto implica leer e imprimir el archivo en el punto que desea hacer el cambio, hacer el cambio, entonces la lectura y imprimiendo 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 simularlo.

programa A Perl para hacer estas tareas toma la forma básica de la apertura de un archivo, imprimir sus líneas, a continuación, cierre 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 esa forma básica, añadir las piezas que usted necesita para insertar, cambiar o eliminar líneas

Para anteponer las 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 top\n"; # <--- 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 bucle while. En este caso, el código encuentra todas las versiones en minúscula de "perl" y las mayúsculas. Sucede para cada línea, ¡así que asegúrese de hacer eso en todas las líneas!

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 top\n"; 

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

close $out; 

Para cambiar sólo 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 saltear líneas, use los controles de bucle. El next en este ejemplo omite las líneas de comentarios, y el last detiene todo el procesamiento una vez que encuentra __END__ o __DATA__.

while(<$in>) 
    { 
    next if /^\s+#/;    # skip comment lines 
    last if /^__(END|DATA)__$/; # stop at end of code marker 
    print $out $_; 
    } 

hacer el mismo tipo de cosas para eliminar una línea en particular mediante el uso de next a saltar las líneas que no desea que aparezca en la salida. Este ejemplo se salta cada cinco líneas:

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

Si, por alguna extraña razón, que realmente quiere ver todo el archivo a la vez en lugar de procesar la línea por línea, puede sorber en (siempre y cuando se puede adaptarse a toda la cosa 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; 

módulos como File::Slurp y Tie::File pueden ayudar con eso también. Si puede, sin embargo, evite leer todo el archivo a la vez. Perl no devolverá esa memoria al sistema operativo hasta que el proceso finalice.

También puede usar uniones Perl para modificar un archivo en el lugar. Lo siguiente cambia todo 'Fred' a 'Barney' en inFile.txt, sobrescribiendo el archivo con los nuevos contenidos.Con el conmutador -p, Perl ajusta un bucle while alrededor del código que especifique con -e, y -i activa la edición in situ. La línea actual está en $_. Con -p, Perl imprime automáticamente el valor de $_ al final del ciclo. Ver perlrun para más detalles.

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

Para realizar una copia de seguridad de inFile.txt, dan -i un archivo de extensión para agregar:

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

Para cambiar sólo la quinta línea, puede agregar una prueba de comprobación $., el número de línea de entrada, a continuación, Sólo realizar la operación cuando se supera la prueba: (o líneas)

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

Para agregar líneas antes de una determinada línea, se puede añadir una línea antes Perl imprime $_:

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

puede incluso añadir una línea al comienzo de un archivo, ya que las impresiones de la línea de corriente al final del bucle:

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

Para insertar una línea después de que uno ya en el archivo, use el interruptor -n. Es como -p, excepto que no imprime $_ al final del ciclo, por lo que debe hacerlo usted mismo. En este caso, primero imprima $_, luego imprima la línea que desea agregar.

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

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

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

    ... or ... 

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

Me pregunto, ¿por qué no funciona cuando escribimos 'perl - pastel ... '? – Zaid

+0

-pie no funciona porque -i espera un argumento y cree que la 'e' pertenece a él. –

Cuestiones relacionadas