Como posso acrescentar uma contagem incremental a cada palavra predefinida de um arquivo de texto?

Como posso acrescentar uma contagem incremental a cada palavra predefinida de um arquivo de texto?

Como posso acrescentar uma contagem incremental a cada palavra predefinida de um arquivo de texto?

Assim como esta pergunta: Como posso acrescentar uma contagem incremental a cada linha de um arquivo de texto?

Quero adicionar uma contagem incremental a um arquivo de texto. Mas em vez de adicionar uma contagem incremental a cada linha, gostaria de adicionar uma contagem incremental a uma palavra predefinida.

Por exemplo, se eu quiser contar a palavra 'cinema' no texto, gostaria que todas as ocorrências de 'cinema' fossem alteradas para 'cinemaN', onde N é o número incremental e o valor máximo de N depende de quantos vezes a palavra 'cinema' ocorre no texto.

Para que um arquivo de texto de entrada contenha este texto:

Ele dirigiu seu carro para o cinema. Ele então entrou no cinema para comprar ingressos e depois descobriu que já fazia mais de dois anos desde a última vez que visitou o cinema.

Gera um arquivo de saída com este conteúdo:

Ele dirigiu seu carro até o cinema1. Entrou então no cinema2 para comprar ingressos e depois descobriu que já fazia mais de dois anos desde a última vez que visitou o cinema3.

De preferência, também gostaria de poder numerar a palavra selecionada em ordem inversa.

Ou seja, isso geraria um segundo arquivo de saída com este conteúdo:

Ele dirigiu seu carro até o cinema3. Entrou então no cinema2 para comprar ingressos e depois descobriu que já fazia mais de dois anos desde a última vez que visitou o cinema1.

Responder1

Eu preferiria perlpara isso:

$ 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\bpalavra a ser pesquisada, usando limites de palavras para que não corresponda como parte parcial de outra palavra. Por exemplo, \bpar\bnão corresponderá apartou parkouspar
  • gea gbandeira é para substituição global. epermite usar código Perl na seção de substituição
  • $&.++$ié a concatenação da palavra correspondente e do valor pré-incrementado $ique tem o valor padrão de0


Para reverter, precisamos primeiro obter a contagem...

$ 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.
  • ctorna-se variável de ambiente acessível através do hash%ENV

ou, perlsozinho, sorvendo o arquivo inteiro

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

Responder2

Com GNU awk para RS multi-char, correspondência sem distinção entre maiúsculas e minúsculas e limites de palavras:

$ 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.

Responder3

Levando em consideração a pontuação após a palavra.
Numeração direta:

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

Numeração inversa:

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

Responder4

Para marcar a palavra em ordem decrescente invertemos o regex E invertemos os dados e finalmente invertemos a data mais uma vez para efetuar a transformação:

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 marcar a palavra em ordem crescente, fazemos uma busca por trás da palavra:

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.

informação relacionada