Pesquise com caracteres diacríticos / acentos com o comando `localizar`

8

Às vezes, preciso pesquisar arquivos com caracteres acentuados (diacríticos em geral), geralmente com localize / mlocate. Desejo configurar (talvez em /etc/updatedb.conf), para que eu procure esses caracteres especiais usando um determinado mapeamento de idioma, por exemplo:

a == âàáäÂÀÂÄ
e == êèéëÊÈÉË
i == îïíÎÏ
o == ôöóÔÖ
u == ûùüÛÜÙ
c == çÇ
n == ñ

Portanto, locate -i liberaciónprocure também arquivos com string liberacion e até liberaciòn .

Notas e premissas

  • E talvez outros: ÊÊÊÊÌÍÎÏ ÏÑÒÓÔÕØØÙÚÛÜÝÞ ßàáâãäåæç èéêëìíîïðñòóôõö øùúûüýþÿ .
  • Essa é uma situação comum em idiomas românticos como espanhol, francês e alemão.
  • Estou sempre usando um código de idioma 100% UTF-8.
  • Eu preferiria não ter que usar expressões regulares.
  • Um patch pode usar transliterações ASCII de Unicode, como o Unidecode / cUnidecode . A maior parte do mlocate está escrita em C.

Relacionado

Pablo Bianchi
fonte

Respostas:

3

Se dermos uma olhada updatedb.conf(5), descobriremos que não podemos fazer muito com itens de configuração.

Então, vamos escrever um script usando locate; No final, somos capazes de executar algo como my-locate.sh liberacionou my-locate.sh liberâciòne isso nos trará todas as combinações possíveis.


Vamos começar

Primeiro, crie um arquivo simples como nosso banco de dados em qualquer lugar que você queira, por exemplo ~/.mydb:; adicione seus caracteres de acento nesse arquivo da seguinte maneira:

aâàáäÂÀÂÄ
eêèéëÊÈÉË
iîïíÎÏ
uûùüÛÜÙ
cçÇ
oôöóÔÖóòòò
...
...

Então precisamos de um pequeno script que faça o trabalho para nós, escrevi um simples:

#!/bin/bash

# Final search term 
STR=""

# Loop throughout all characters of desired string
for (( i=0; i<${#1}; i++ )); do

  # Split the string in one char
  CH="${1:$i:1}"

  # Find all possible combinations of this char
  CHARS=$(grep "$CH" ~/.mydb)

  # Add an "or" operator between characters
  REG=$(echo "$CHARS" |  sed 's/.\{1\}/&\|/g' )
  REG="($REG)"

  # Append all possible combination of this character
  # to our final search term as an or statement
  if [ "$REG" == '()' ];
  then
   STR=$STR$CH
  else
   STR=$STR$REG
  fi

done

# locate it using regex
locate --regex "$STR$"

Agora salve-o em algum lugar do seu PATH com o nome desejado, por exemplo: in ~/bin. Já deve estar no seu ambiente PATH.

Afinal, basta usar algo assim para pesquisar todas as combinações possíveis.

my-locate.sh liberacion

Encontrará para mim tudo isso:

~/lab/liberacion
~/lab/liberaciòn
~/lab/liberación
~/lab/liberâciòn
~/lab/liberäciòn
~/lab/libÈrâciòn
Ravexina
fonte
Você pode usar grep -fou fgrepevitar a interpretação de "$CH"um caractere especial, por exemplo grep ^, corresponderia a qualquer linha, mas grep -f ^corresponderá apenas àquelas que contêm o caractere ^. Também pode ser mais fácil usar classes de caracteres para criar a expressão regular, ou seja, REG="[$CHARS]"é provavelmente mais fácil que o seu sedcomando. Cuidado com caracteres especiais! Caso contrário, uma boa abordagem. +1
David Foerster
2

Agora, com o mlocate 0.26, temos a -t --transliterateopção (veja a página de manual ) no Ubuntu 18.04+ (sem a necessidade de soluções alternativas):

Criando alguns arquivos de teste:

$ touch liberación liberacion liberaciôn

Atualização e pesquisa:

$ updatedb
$ locate --transliterate liberacion 
/home/pablo/liberacion
/home/pablo/liberación
/home/pablo/liberaciôn

Então agora locate -t liberacióntambém procure arquivos com string liberacione atéliberaciòn !

Por fim, criando um alias no meu .bashrc :-)

$ alias locate="locate --transliterate"
Pablo Bianchi
fonte