it-swarm-pt.tech

Como posso contar o número de ocorrências de uma palavra em um arquivo de texto com a linha de comando?

Eu tenho um arquivo JSON grande que está em uma linha e quero usar a linha de comando para poder contar o número de ocorrências de uma palavra no arquivo. Como eu posso fazer isso?

45
mythz
$ tr ' ' '\n' < FILE | grep Word | wc -l

Onde tr substitui espaços por novas linhas, grep filtra todas as linhas resultantes correspondentes ao Word e wc conta as restantes.

Pode-se até salvar a parte wc usando o -c opção de grep:

$ tr ' ' '\n' < FILE | grep -c Word

O -c opção é definida pelo POSIX.

Se não for garantido que haja espaços entre as palavras, você deverá usar outro caractere (como delimitador) para substituir. Por exemplo, tr partes alternativas são

tr '"' '\n'

ou

tr "'" '\n'

se você deseja substituir aspas simples ou duplas. Obviamente, você também pode usar tr para substituir vários caracteres ao mesmo tempo (pense em diferentes tipos de espaço em branco e pontuação).

Caso você precise contar o Word, mas não o prefixoWORD, WORDsuffix ou prefixWORDsuffix, você pode colocar o padrão do Word nos marcadores de início/fim de linha:

grep -c '^Word$'

O que é equivalente aos marcadores de início/fim do Word, em nosso contexto:

grep -c '\<Word\>'
48
maxschlepzig

Com GNU grep, isso funciona: grep -o '\<Word\>' | wc -l

-o imprime cada parte correspondente de cada linha em uma linha separada.

\< afirma o início de uma palavra e \> afirma o final de uma palavra (semelhante à de Perl \b), portanto, isso garante que você não corresponda a uma string no meio de uma palavra.

Por exemplo,

$ python -c 'importa isso' | grep '\ <one \>' 
 Deve haver 1- e de preferência apenas 1 - maneira óbvia de fazê-lo. 
 Os espaços para nome são 1 buzinando ótima idéia - vamos fazer mais dessas! 
$ python -c 'importa isso' | grep -o '\ <one \>' 
111$ python -c 'importa isso' | grep -o '\ <one \>' | wc -l 
 3 
25
ephemient

Infelizmente não funciona com GNU coreutils.

grep -o -c Word file

Se funcionar na sua plataforma, é uma solução elegante e bastante intuitiva; mas as pessoas GNU ainda estão pensando.

11
tripleee
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

Este comando faz o seguinte:

  1. Substitua todos os caracteres não alfanuméricos por um espaço em branco.
  2. Todas as quebras de linha também são convertidas em espaços.
  3. Reduz todos os vários espaços em branco para um espaço em branco
  4. Todos os espaços agora são convertidos em quebras de linha. Cada palavra em uma linha.
  5. Traduz todas as palavras para minúsculas, para evitar que 'Hello' e 'olá' sejam palavras diferentes
  6. Classifica o texto
  7. Conta e remove as linhas iguais
  8. Classifica reversa para contar as palavras mais frequentes
  9. Adicione um número de linha a cada palavra para conhecer a posição da palavra no todo

Por exemplo, se eu quiser analisar a primeira mensagem de Linus Torvald:

De: [email protected] (Linus Benedict Torvalds) Grupos de notícias: comp.os.minix Assunto: O que você mais gostaria de ver no minix? Resumo: pequena pesquisa para o meu novo sistema operacional ID da mensagem: <[email protected]> Data: 25 de agosto de 91 20:57:08 GMT Organização: Universidade de Helsinque

Olá pessoal, usando o minix -

Estou desenvolvendo um sistema operacional (gratuito) (apenas um hobby, não será grande e profissional como o GNU) para 386 (486) AT clones. Isso está sendo produzido desde abril e está começando a ficar pronto.Gostaria de receber algum feedback sobre coisas que as pessoas gostam/não gostam no minix, pois meu sistema operacional se assemelha um pouco (mesmo layout físico do sistema de arquivos (devido a razões práticas) entre outras coisas).

No momento, eu portado bash (1.08) e gcc (1.40), e as coisas parecem funcionar. Isso implica que vou conseguir algo prático em alguns meses e gostaria de saber quais recursos a maioria das pessoas gostaria. Todas as sugestões são bem-vindas, mas não prometo implementá-las ????

Linus ([email protected])

PS. Sim - ele é livre de qualquer código minix e possui um fs multiencadeado. NÃO é protegido (usa 386 alternância de tarefas etc.) e provavelmente nunca suportará nada além de discos rígidos AT, pois é tudo o que tenho : .

Eu crio um arquivo chamado linus.txt , colo o conteúdo e depois escrevo no console:

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

A saída seria:

 1        7 i
 2        5 to
 3        5 like
 4        5 it
 5        5 and
 6        4 minix
 7        4 a
 8        3 torvalds
 9        3 of
10        3 helsinki
11        3 fi
12        3 any
13        2 would
14        2 won
15        2 what
16        ...

Se você deseja visualizar apenas as primeiras 20 palavras:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20

É importante observar que o comando tr 'AZ' 'a-z' não suporta UTF-8 --- (ainda , para que em idiomas estrangeiros a palavra APR theS seja traduzida como aprÈs.

Se você deseja apenas procurar a ocorrência de uma palavra, adicione um grep no final:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"

Em um script chamado search_freq :

#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"

O script deve ser chamado:

 search_freq Word_to_search_for
7
Roger Borrell

Dependendo se você deseja corresponder ao Word nas chaves ou nos valores dos dados JSON, é provável que você deseje extrair apenas chaves ou apenas valores dos dados. Caso contrário, você poderá contar algumas palavras muitas vezes se elas ocorrerem como chaves e valores.

Para extrair todas as chaves:

jq -r '..|objects|keys[]' <file.json

Isso testa recursivamente se a coisa atual é um objeto e, se for, extrai as chaves. A saída será uma lista de chaves, uma por linha.

Para extrair todos os valores:

jq -r '..|scalars' <file.json

Isso funciona de maneira semelhante, mas possui menos etapas.

Você pode canalizar a saída acima através de grep -c 'PATTERN' (para combinar algum padrão com as chaves ou valores) ou grep -c -w -F 'Word' (para corresponder a Word nas chaves ou valores) ou grep -c -x -F 'Word' (para corresponder a uma chave ou valor completo), ou similar, para fazer sua contagem.

3
Kusalananda

Eu tenho json com algo assim: "number":"OK","number":OK" repetido várias vezes em uma linha.

Meu contador "OK" simples:

sed "s|,|\n|g" response | grep -c OK

0
khazad-dum_miner

Usando grep -c você contará apenas as linhas, uma linha pode ter muitas ocorrências da Palavra.

Isso faria isso:

grep -o Word foo|wc -l
0
Ramiro Velazquez