Pesquisa Regex para raízes de palavras com prefixos comuns

3

Eu recentemente tive uma curiosidade sobre palavras no dicionário que compartilham tanto "pro-" como "con" como um prefixo. Assim, por exemplo, procissão / concessão, produzir / conduzir, professar / confessar, progresso / congresso, e assim por diante. Eu estou basicamente procurando por quaisquer palavras que correspondam a ^pro(.+)$ e ^con(.+)$ , onde o conteúdo do grupo de captura é o mesmo.

Meu primeiro comando homem das cavernas foi:

sed -nr 's/^con(.+)$//Ip' /usr/share/dict/words | \
xargs -I SUFFIX -n1 grep -i '^proSUFFIX$' /usr/share/dict/words

Parece funcionar, produzindo uma palavra "cont" completa, desde que exista uma palavra "pró" correspondente. O problema é que é slooow. Ele invoca grep para cada correspondência em potencial, solicitando a varredura de todo o dicionário a cada vez. Eu poderia acelerar isso fazendo um arquivo temporário que só tem palavras pro / con, mas parece que deve haver alguma maneira eficiente de fazer isso sem escrever um arquivo.

Existe uma ferramenta no mundo GNU que é bem adequada para este tipo de pesquisa de intersecção?

    
por smitelli 28.07.2015 / 22:03

3 respostas

2

Do meu comentário anterior à pergunta em si:

egrep '^(pro|con).* /usr/share/dict/words | sed -nE 's/^(pro|con)(.*)//p' | sort | uniq -d 

fornecerá uma lista de todas as bases de palavras com prefixo pro e con:

O egrep inicial pega todas as palavras com os prefixos pro e con . Em seguida, usamos sed para remover pro e con do início de cada palavra, sort da lista e, em seguida, usamos uniq -d para exibir as entradas ony na lista que tem duplicatas.

    
por 28.07.2015 / 22:20
0

Isso imprimirá as palavras sem o prefixo pro | con:

grep '^\(pro\|con\)' /usr/share/dict/words | cut -c 4- | sort | uniq -c | awk '$1 == 2 {print $2}'
    
por 28.07.2015 / 22:17
0

Nesse caso específico - entrada classificada, então todas as palavras con... estão listadas antes de pro... palavras - você pode usar awk para armazenar as linhas correspondentes a ^con em uma matriz e quando você atingir as linhas correspondentes a ^pro , substitua pro por con e, se o resultado estiver em matriz, imprima a palavra raiz:

awk '/^con/{arr[$0]=$0}; /^pro/{c=gensub(/pro/, "con", 1)
if (c in arr) print substr(c, 4)}' /usr/share/dict/words
.....
.....
vince
vinces
vocation
vocation's
vocations
voke
voked
vokes
voking
    
por 04.10.2015 / 12:13