¿Cómo puedo agregar un recuento incremental a cada palabra predefinida de un archivo de texto?

¿Cómo puedo agregar un recuento incremental a cada palabra predefinida de un archivo de texto?

¿Cómo puedo agregar un recuento incremental a cada palabra predefinida de un archivo de texto?

Como esta pregunta: ¿Cómo puedo agregar un recuento incremental a cada línea de un archivo de texto?

Quiero agregar un recuento incremental a un archivo de texto. Pero en lugar de agregar un recuento incremental a cada línea, me gustaría agregar un recuento incremental a una palabra predefinida.

Por ejemplo, si quiero contar la palabra "cine" en el texto, me gustaría que todas las apariciones de "cine" se cambien a "cinemaN", donde N es el número incremental y el valor máximo de N depende de cuántas veces aparece la palabra "cine" en el texto.

De modo que un archivo de texto de entrada que contenga este texto:

Condujo su coche al cine. Luego entró al cine para comprar entradas y luego descubrió que habían pasado más de dos años desde la última vez que visitó el cine.

Genera un archivo de salida con este contenido:

Condujo su coche al cine1. Luego entró al cine2 para comprar entradas y luego descubrió que habían pasado más de dos años desde la última vez que visitó el cine3.

Preferiblemente también me gustaría poder numerar la palabra seleccionada en orden inverso.

Es decir, esto generaría un segundo archivo de salida con este contenido:

Condujo su coche al cine3. Luego entró al cine2 para comprar entradas y luego descubrió que habían pasado más de dos años desde la última vez que visitó el cine1.

Respuesta1

Preferiría perlesto:

$ cat ip.txt 
He drove his car to the cinema. He then went inside the cinema to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema.

$ # forward counting is easy
$ perl -pe 's/\bcinema\b/$&.++$i/ge' ip.txt 
He drove his car to the cinema1. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema3.
  • \bcinema\bpalabra a buscar, usando límites de palabras para que no coincida como parte parcial de otra palabra. Por ejemplo, \bpar\bno coincidirá apartcon o parkospar
  • gela gbandera es para reemplazo global. epermite utilizar código Perl en la sección de reemplazo
  • $&.++$ies una concatenación de una palabra coincidente y un valor preincrementado cuyo $ivalor predeterminado es0


Para revertir, primero necesitamos obtener el conteo...

$ c=$(grep -ow 'cinema' ip.txt | wc -l) perl -pe 's/\bcinema\b/$&.$ENV{c}--/ge' ip.txt 
He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema1.
  • cse convierte en una variable de entorno accesible a través del hash%ENV

o, perlsolo, sorbiendo la lima entera

perl -0777 -pe '$c=()=/\bcinema\b/g; s//$&.$c--/ge' ip.txt 

Respuesta2

Con GNU awk para RS de varios caracteres, coincidencia que no distingue entre mayúsculas y minúsculas y límites de palabras:

$ awk -v RS='^$' -v ORS= -v word='cinema' '
    BEGIN { IGNORECASE=1 }
    { cnt=gsub("\\<"word"\\>","&"); while (sub("\\<"word"\\>","&"cnt--)); print }
' file
He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema1.

Respuesta3

Teniendo en cuenta la puntuación después de la palabra.
Numeración directa:

word="cinema"
awk -v word="$word" '
    { 
      for (i = 1; i <= NF; i++) 
        if ($i ~ word "([,.;:)]|$)") { 
          gsub(word, word "" ++count,$i) 
        }
      print 
    }' input-file

Numeración hacia atrás:

word="cinema"
count="$(awk -v word="$word" '
    { count += gsub(word, "") }
    END { print count }' input-file)"
awk -v word="$word" -v count="$count" '
    { 
      for (i = 1; i <= NF; i++) 
        if ($i ~ word "([,.;:)]|$)") { 
          gsub(word, word "" count--, $i) 
        }
      print 
    }' input-file

Respuesta4

Para etiquetar la palabra en orden decreciente invertimos la expresión regular E invertimos los datos y finalmente invertimos la fecha una vez más para efectuar la transformación:

perl -l -0777pe '$_ = reverse reverse =~ s/(?=\bamenic\b)/++$a/gre' input.data

Resultado

He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and
afterwards discovered that it was more then two years since he last visited the cinema1.

Para etiquetar la palabra en orden creciente, realizamos una búsqueda retrospectiva de la palabra:

perl -lpe 's/\bcinema\b\K/++$a/eg' input.data

Resultado

He drove his car to the cinema1. He then went inside the cinema2 to purchase tickets, and
afterwards discovered that it was more then two years since he last visited the cinema3.

información relacionada