Поиск с диакритическими знаками / символами ударения с помощью команды `locate`

8

Иногда мне нужно искать файлы с акцентированными символами (диакритические знаки в целом), обычно с помощью locate / mlocate. Я хочу настроить (может быть, в /etc/updatedb.conf), чтобы он позволял мне искать эти специальные символы с использованием определенного языкового отображения, например:

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

Так locate -i liberaciónже искать файлы с струнной Liberacion и даже Liberacion .

Примечания и предположения

  • И, может быть, другие: ÂÃÄÁÁÅÆ ÇÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæç èéêëìíîïðñòóôôõöö øùúûüýþÿ .
  • Это распространенная ситуация на романских языках, таких как испанский, французский и немецкий.
  • Я всегда использую локаль 100% UTF-8.
  • Я бы предпочел не использовать регулярные выражения.
  • Патч может использовать транслитерации ASCII Unicode, как это делает Unidecode / cUnidecode . Большая часть mlocate написана на C.

связанные с

Пабло Бьянки
источник

Ответы:

3

Если мы посмотрим updatedb.conf(5), мы обнаружим, что мы ничего не можем сделать с элементами конфигурации.

Итак, мы собираемся написать сценарий с использованием locate; В конце мы можем запустить что-то вроде my-locate.sh liberacionили, my-locate.sh liberâciònи это принесет нам все возможные комбинации.


Давайте начнем

Сначала создайте простой файл в качестве нашей базы данных там, где вы хотите, например ~/.mydb:; затем добавьте ваши символы ударения в этот файл следующим образом:

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

Затем нам нужен небольшой скрипт, который сделает всю работу за нас, я написал простой:

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

Теперь сохраните его где-нибудь в вашей переменной PATH с нужным именем, например: in ~/bin. Это должно быть уже в вашей среде PATH.

В конце концов, просто используйте что-то подобное для поиска всех возможных комбинаций.

my-locate.sh liberacion

Найдете для меня все это:

~/lab/liberacion
~/lab/liberaciòn
~/lab/liberación
~/lab/liberâciòn
~/lab/liberäciòn
~/lab/libÈrâciòn
Ravexina
источник
Вы можете использовать grep -fили, fgrepчтобы избежать интерпретации "$CH"в качестве специального символа, например grep ^, соответствует любой строке, но соответствует grep -f ^только тем, которые содержат символ ^. Также может быть проще использовать классы символов для создания регулярного выражения, т.е. REG="[$CHARS]", вероятно, проще, чем ваша sedкоманда. Остерегайтесь специальных символов, хотя! В противном случае хороший подход. +1
Дэвид Фёрстер
2

Теперь с mlocate 0.26 у нас есть -t --transliterateопция (см. Справочную страницу ) в Ubuntu 18.04+ (без необходимости использования нечетных обходных путей):

Создание некоторых тестовых файлов:

$ touch liberación liberacion liberaciôn

Обновление и поиск:

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

Так что теперь locate -t liberaciónтакже искать файлы со строкой liberacionи дажеliberaciòn !

Наконец, создание псевдонима на моем .bashrc :-)

$ alias locate="locate --transliterate"
Пабло Бьянки
источник