Unix - Encontrando nomes com egrep

2

Estou tentando criar um script egrep para distinguir nomes - palavras que são escritas com maiúsculas iniciais, como países, nomes de pessoas, etc. - em um conjunto de arquivos txt. Eu quero ignorar números e selecionar todas as palavras em maiúsculas, somente a palavra, excluindo aquelas que estão no início de uma frase (então, seguindo '.') Outros padrões recomendados também são bem-vindos

Um exemplo de entrada pode ser:

General public interest in whether there is water on Mars has been a perennial interest since the the 1800s. In 1877, when Mars approached Earth almost as closely as it could (still a rather distant 56 million kilometres away), the Italian astronomer Giovanni Schiaparelli observed the Red Planet. He made maps of the surface features that he saw, including what looked like a network of channels.

saída seria:

Earth
Giovanni
Italian
Mars
Planet
Red
Schiparelli
    
por patimadison 28.09.2015 / 15:56

1 resposta

2

Uma maneira de fazer isso seria i) remover todas as novas linhas para que a coisa toda seja uma cadeia longa e você evite corresponder as primeiras palavras das frases cujo ponto final anterior estivesse na linha anterior e ii) localizar todas as palavras cuja primeira letra é maiúscula e cujo caractere precedente não é um dos . , ? , ! . Por exemplo:

$ tr '\n' ' ' < file | grep -Po '(?<![.!?]) \K[A-Z]\w+' 
Mars
Mars
Earth
Italian
Giovanni
Schiaparelli
Red
Planet

E para remover entradas duplicadas:

$ tr '\n' ' ' < file  | grep -Po '(?<![.!?]) \K[A-Z]\w+' | sort -u
Earth
Giovanni
Italian
Mars
Planet
Red
Schiaparelli

O tr substitui as novas linhas por espaços. A opção -P ativa o suporte à Perreg Compatible Regular Expression (PCRE), que nos fornece os recursos avançados que estamos usando. O -o significa "imprimir apenas a parte correspondente da linha".

A expressão regular usa um lookbehind negativo ( (?>!foo) ) para garantir que correspondamos apenas a nada, exceto a ? , ! ou . , então um espaço e, em seguida, uma letra maiúscula [A-Z] seguida por um ou mais caracteres de palavra.

Observe que isso falhará se:

  • um nome é a primeira palavra do arquivo;
  • um nome é a primeira palavra de uma frase;
  • você tem nomes compostos como María de Quinto, ele corresponderá a María e Quinto , mas ignorará o de .

Se o seu grep não suportar as opções -P ou -o , você poderá usar o Perl:

perl -0lne 'print join "\n",(/(?<![.!?]) \K[A-Z]\w+/g)' file | sort -u
    
por 28.09.2015 / 19:02