Recherche avec des caractères diacritiques / accentués avec la commande `Locate`


8

Parfois, j'ai besoin de rechercher des fichiers avec des caractères accentués (diacritique en général), généralement avec Locate / mlocate. Je souhaite configurer (peut-être en /etc/updatedb.conf) afin qu'il me permette de rechercher ces caractères spéciaux en utilisant un certain mappage de langue, par exemple:

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

Donc locate -i liberaciónégalement rechercher des fichiers avec chaîne Liberación et même Liberación .

Notes et hypothèses

  • Et peut-être d'autres: ÂÃÄÀÁÅÆ ÇÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæç èéêëìíîïðñòóôõö øùúûüýþÿ .
  • Il s'agit d'une situation courante sur les langues romanes comme l'espagnol, le français et l'allemand.
  • J'utilise toujours une locale 100% UTF-8.
  • Je préfère ne pas avoir à utiliser d'expressions régulières.
  • Un patch peut utiliser des translittérations ASCII d'Unicode comme le fait Unidecode / cUnidecode . La plupart de mlocate est écrit sur C.

en relation

Réponses:


3

Si nous y jetons un coup d'œil updatedb.conf(5), nous constaterons que nous ne pouvons pas faire grand-chose avec les éléments de configuration.

Nous allons donc écrire un script en utilisant locate; À la fin, nous pouvons exécuter quelque chose comme my-locate.sh liberacionou my-locate.sh liberâciònet cela nous apportera toutes les combinaisons possibles.


Commençons

Créez d'abord un fichier simple comme base de données où vous le souhaitez, par exemple ~/.mydb:; puis ajoutez vos caractères accentués dans ce fichier comme ceci:

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

Ensuite, nous avons besoin d'un petit script qui fait le travail pour nous, j'en ai écrit un simple:

#!/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$"

Maintenant, enregistrez-le quelque part dans votre CHEMIN avec le nom souhaité, par exemple: in ~/bin. Il devrait déjà être dans votre environnement PATH.

Après tout, utilisez simplement quelque chose comme ça pour rechercher toutes les combinaisons possibles.

my-locate.sh liberacion

Trouvera pour moi tous ces éléments:

~/lab/liberacion
~/lab/liberaciòn
~/lab/liberación
~/lab/liberâciòn
~/lab/liberäciòn
~/lab/libÈrâciòn

Vous pouvez utiliser grep -fou fgreppour éviter l'interprétation de "$CH"comme un caractère spécial, par exemple grep ^correspondrait à n'importe quelle ligne mais grep -f ^ne correspond qu'à celles qui contiennent le caractère ^. Il peut également être plus facile d'utiliser des classes de caractères pour créer l'expression régulière, c'est REG="[$CHARS]"-à- dire qu'il est probablement plus facile que votre sedcommande. Attention aux caractères spéciaux! Sinon, une bonne approche. +1
David Foerster

2

Maintenant, avec mlocate 0.26, nous avons une -t --transliterateoption (voir la page de manuel ) sur Ubuntu 18.04+ (sans avoir besoin de solutions de contournement):

Création de fichiers de test:

$ touch liberación liberacion liberaciôn

Mise à jour et recherche:

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

Alors maintenant, locate -t liberaciónrecherchez également des fichiers avec chaîne liberacionet mêmeliberaciòn !

Enfin, créer un alias sur mon .bashrc :-)

$ alias locate="locate --transliterate"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.