Szukaj za pomocą znaków diakrytycznych / akcentujących za pomocą polecenia „locate”

8

Czasami muszę wyszukiwać pliki ze znakami akcentowanymi (ogólnie diakrytycznymi), zwykle za pomocą locate / mlocate. Chcę skonfigurować (być może /etc/updatedb.conf), aby pozwoliła mi wyszukiwać znaki specjalne przy użyciu określonego odwzorowania języka, na przykład:

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

Tak locate -i liberaciónteż wyszukać pliki z ciągiem Liberación a nawet Liberación .

Uwagi i założenia

  • A może inni: ÂÃĘÀÁÅÆ ÇÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖØ'ÚÛÜÝÞ ßàáâãäåæç èéêëìíîïðñòóôõö øùúûüýþÿ .
  • Jest to powszechna sytuacja w przypadku języków romańskich, takich jak hiszpański, francuski i niemiecki.
  • Zawsze używam ustawień regionalnych 100% UTF-8.
  • Wolałbym nie używać wyrażeń regularnych.
  • Łatka może wykorzystywać transliteracje ASCII Unicode, jak robi to Unidecode / cUnidecode . Większość mlocate jest napisana na C.

Związane z

Pablo Bianchi
źródło

Odpowiedzi:

3

Jeśli przyjrzymy się temu updatedb.conf(5), przekonamy się, że niewiele możemy zrobić z elementami konfiguracji.

Więc napiszemy skrypt za pomocą locate; Na koniec jesteśmy w stanie uruchomić coś w stylu my-locate.sh liberacionlub, my-locate.sh liberâciòna to zapewni nam wszystkie możliwe kombinacje.


Zaczynajmy

Najpierw utwórz prosty plik jako naszą bazę danych, gdziekolwiek chcesz, np .: ~/.mydb; następnie dodaj znaki akcentu do tego pliku w następujący sposób:

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

Następnie potrzebujemy małego skryptu, który spełni nasze zadanie, napisałem prosty:

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

Teraz zapisz go gdzieś w ŚCIEŻCE z żądaną nazwą, np ~/bin. W. Powinien już znajdować się w środowisku PATH.

W końcu po prostu użyj czegoś takiego, aby wyszukać wszystkie możliwe kombinacje.

my-locate.sh liberacion

Znajdzie dla mnie wszystkie z nich:

~/lab/liberacion
~/lab/liberaciòn
~/lab/liberación
~/lab/liberâciòn
~/lab/liberäciòn
~/lab/libÈrâciòn
Ravexina
źródło
Możesz użyć grep -flub, fgrepaby uniknąć interpretacji "$CH"znaku specjalnego, np. grep ^Pasuje do dowolnej linii, ale grep -f ^pasuje tylko do tych, które zawierają znak ^. Może być również łatwiej używać klas postaci do tworzenia wyrażeń regularnych, tzn. REG="[$CHARS]"Prawdopodobnie jest łatwiejsze niż twoje sedpolecenie. Uważaj jednak na znaki specjalne! W przeciwnym razie dobre podejście. +1
David Foerster
2

Teraz z mlocate 0.26 mamy -t --transliterateopcję (patrz strona podręcznika) na Ubuntu 18.04+ (bez konieczności dziwnych obejść):

Tworzenie niektórych plików testowych:

$ touch liberación liberacion liberaciôn

Zaktualizuj i wyszukaj:

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

Więc teraz locate -t liberaciónrównież wyszukiwać pliki z ciągiem liberacion, a nawetliberaciòn !

Wreszcie, tworzenie aliasu na moim .bashrc :-)

$ alias locate="locate --transliterate"
Pablo Bianchi
źródło