Buscar con caracteres diacríticos / acentos con el comando `localizar`

8

A veces necesito buscar archivos con caracteres acentuados (diacríticos en general), generalmente con localizar / ubicar. Deseo configurar (tal vez en /etc/updatedb.conf) para que me permita buscar estos caracteres especiales utilizando una asignación de idioma determinada, por ejemplo:

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

Por lo tanto, locate -i liberacióntambién busque archivos con liberacion de cadenas e incluso liberaciòn .

Notas y supuestos

  • Y tal vez otros: ÂÃÄÀÁÅÆ ÇÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæç èéêëìíîïðñòóôõö øùúûüýþÿ .
  • Esta es una situación común en lenguas romances como español, francés y alemán.
  • Siempre estoy usando un entorno local 100% UTF-8.
  • Preferiría no tener que usar expresiones regulares.
  • Un parche puede usar transcripciones ASCII de Unicode como lo hace Unidecode / cUnidecode . La mayor parte de mlocate está escrito en C.

Relacionado

Pablo Bianchi
fuente

Respuestas:

3

Si echamos un vistazo updatedb.conf(5), descubriremos que no hay mucho que podamos hacer con los elementos de configuración.

Entonces vamos a escribir un script usando locate; Al final podemos ejecutar algo como my-locate.sh liberaciono my-locate.sh liberâciòny nos traerá todas las combinaciones posibles.


Empecemos

Primero cree un archivo simple como nuestra base de datos en cualquier lugar que desee, por ejemplo ~/.mydb:; luego agregue sus caracteres de acentos en ese archivo de esta manera:

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

Luego necesitamos un pequeño script que haga el trabajo por nosotros, escribí uno 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$"

Ahora guárdelo en algún lugar de su RUTA con el nombre deseado, por ejemplo: en ~/bin. Ya debería estar en su entorno PATH.

Después de todo, simplemente use algo como esto para buscar todas las combinaciones posibles.

my-locate.sh liberacion

Encontrará para mí todo esto:

~/lab/liberacion
~/lab/liberaciòn
~/lab/liberación
~/lab/liberâciòn
~/lab/liberäciòn
~/lab/libÈrâciòn
Ravexina
fuente
Puede usar grep -fo fgrepevitar la interpretación de "$CH"como un carácter especial, por ejemplo grep ^, coincidiría con cualquier línea pero grep -f ^solo coincidiría con las que contienen el carácter ^. También puede ser más fácil usar clases de caracteres para diseñar la expresión regular, REG="[$CHARS]"es decir, probablemente sea más fácil que su sedcomando. ¡Pero ten cuidado con los personajes especiales! De lo contrario, un buen enfoque. +1
David Foerster
2

Ahora con mlocate 0.26 tenemos la -t --transliterateopción (ver la página de manual ) en Ubuntu 18.04+ (sin la necesidad de soluciones extrañas):

Crear algunos archivos de prueba:

$ touch liberación liberacion liberaciôn

Actualización y búsqueda:

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

¡Así que ahora locate -t liberacióntambién busca archivos con cadena liberacione inclusoliberaciòn !

Finalmente, creando un alias en mi .bashrc :-)

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