Como dices que el fichero tiene una cierta estructura, podemos aprovecharla para "extraer" el tercer párrafo.
Supongamos que el texto (texto.txt) sea:
Using text Syntax Highlighting
//
1kfj ljf skldsj fdsfs
fdskljf ldskjf lj
dskflj fljdslkjfdkfjh gkghd
fljg gjlj g fdg
definition
//
2lfdsj jdsfl kfj lf ds
f ldsfj skljf kfldjg df
+fdjh erojerordefsfd
lfdkj fljdg
definition
//
3lkjf ñj fsfdj totofd
totojfd gljtototfdg
fdg dkftotoldj fd gfd
dftototjg jgtotoj gdf
definition
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Cada párrafo empieza por "//" y termina por la palabra
definition.
Dada esa estructura, podemos definir la variable especial "
$/", que es la que define cómo es el separador de los registros de entrada, al valor "//".
De esa forma, cada vez que leamos un registro desde la entrada, nos dará todo el texto que va desde la última posición leída hasta el siguiente "//".
Hay que notar que el primer texto que leemos estará vacío, a causa de que precisamente el texto empieza por ese código. Es como si el primer registro estuviera vacío, así que empezaremos a leer desde el segundo párrafo.
Pero el que nos interesa es sólo el tercer párrafo (el cuarto que leemos). Lo que podemos hacer, para hacerlo más cómodo, es leer cada registro y meterlo en una posición de un array. Luego vamos al tercer elemento y cambiamos los toto por titi.
Finalmente, sacamos a pantalla el texto cambiado.
Este programa hace eso:
Using perl Syntax Highlighting
#!/usr/bin/perl
# Definimos cómo es el separador de registros
$/ = "//";
# Abrimos el fichero
open TXT
, "<texto.txt" or die "No puedo abrir el texto.txt: $!\n";
@bloques = <TXT>; # Leemos todo el fichero, registro por registro
close TXT
;
# Editamos el tercer párrafo
# Recordar que el 0 está vacío, por lo que estará en la cuarta posición
# por lo que entonces será el registro con índice 3 (los arrays empiezan por 0)
$bloques[3] =~ s/toto/titi/g;
# Sacamos el resultado
print $bloques[3
];Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
En una sola línea también se puede hacer:
Using perl Syntax Highlighting
perl
-e
'$/=q(//); @bloques=<>; $bloques[3] =~ s/toto/titi/g; print $bloques[3]' texto
.txt
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Otra forma sería leer sólo el párrafo que nos interesa y meterlo en una variable escalar:
Using perl Syntax Highlighting
$parrafo = (<TXT>)[3
];Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
y luego seguir con la operación de cambio.
Es posible que el fichero sea muy grande, por lo que podríamos tener problemas al intentar leerlo todo de golpe (o ser una operación muy lenta). En ese caso, abriríamos el programa e iríamos línea a línea, procesando en el lugar correcto.
Using perl Syntax Highlighting
#!/usr/bin/perl
use warnings
;
use strict
;
# Contador de en qué bloque nos encontramos
my $en_parrafo = 0;
# Abrimos
open TXT
,"<texto.txt" or die "No puedo abrir el fichero texto.txt: $!\n";
# Leemos por líneas
while ( my $linea = <TXT> ) {
# Si es inicio de bloque, sumamos un párrafo más
if ( $linea =~ m{^//} ) {
$en_parrafo++;
# En el caso de llegar al siguiente párrafo,
# que no nos interesa seguir, salimos del bucle
last if $en_parrafo == 4;
}
# Si estamos dentro del tercer bloque
if ( $en_parrafo == 3 ) {
# Hacemos el cambio del toto -> titi
$linea =~ s/toto/titi/g;
# Salida a pantalla del resultado
print $linea;
}
}
# Cerramos el fichero y nos vamos
close TXT
;Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Otra opción con la que poder jugar: si sabemos que la palabra "definition" va justo delante de la siguiente línea con "//", podríamos definir
$/ como "definition\n//" y de esa manera ya podemos referirnos al tercer bloque como $bloques[2] en vez de $bloques[3].
Bueno... desde luego hay muchas formas de hacerlo.
A ver si alguien se anima con alguna más...