У меня есть каталог, содержащий множество файлов. Более того, я забываю точное имя файла. Поэтому, когда я хочу найти файл, я его не нахожу.
Если есть какой-либо инструмент, использующий алгоритм Soundex для поиска, который был бы полезен в моем случае.
решение1
Это ответ, написанный для моего собственного любопытства. Вам, вероятно, следует построить что-то из предложений в ответах на "Существует ли команда Unix, которая ищет похожие строки, основываясь в основном на том, как они звучат при произнесении?" (модуль Perl Text::Soundex
) вместо использования этого.
Следующий скрипт оболочки и сопутствующий sed
скрипт выполняют поиск имени файла Soundex в дереве каталогов, корнем которого является текущий каталог, с учетом строки поиска в командной строке.
$ sh soundex.sh fissbux
./fizzbuzz
./fizzbuzz.c
./fizzbuzz2
./fizzbuzz2.c
$ sh soundex.sh sharlok
./HackerRank/Algorithms/02-Implementation/17-sherlock_and_squares.c
$ sh soundex.sh sundek
./soundex.sh
./soundex.sed
Скрипт оболочки ( soundex.sh
):
#!/bin/sh
soundex=$( printf '%s\n' "$1" | tr 'a-z' 'A-Z' | sed -f soundex.sed )
find . -exec bash -c '
paste <( printf "%s\n" "${@##*/}" | tr "a-z" "A-Z" | sed -f soundex.sed ) \
<( printf "%s\n" "$@" ) |
awk -vs="$0" "\$1 == s" | cut -f 2-' "$soundex" {} +
Скрипт вычисляет значение soundex для поискового термина с помощью sed
скрипта (ниже). Затем он использует find
для поиска всех имен в текущем каталоге или ниже и вычисляет значение soundex для каждого из них таким же образом, как и для поискового термина. Если значение soundex для имени файла совпадает со значением поискового термина, выводится полный путь к этому файлу.
Признаю, что скрипт оболочки немного примитивен. Например, его можно улучшить, добавив абсолютный путь к скрипту soundex.sed
. В том виде, в котором он написан сейчас, он требует, чтобы скрипт sed
находился в текущем каталоге. Он также не поддерживает имена файлов, содержащие символы новой строки.
Сценарий sed
( soundex.sed
):
s/[^[:alpha:]]//g
h
s/^\(.\).*$/\1/
x
y/bfpvBFPVcgjkqsxzCGJKQSXZdtDTlLmnMNrR/111111112222222222222222333344555566/
s/\([1-6]\)[hwHW]\1/\1/g
s/\([1-6]\)\1\1*/\1/g
s/[aeiouyhwAEIOUYHW]/!/g
s/^.//
H
x
s/\n//
s/!//g
s/^\(....\).*$/\1/
s/^\(...\)$/\10/
s/^\(..\)$/\100/
s/^\(.\)$/\1000/
Это реализует «American Soundex»как описано в Википедии. Он не изменяет начальный символ (кроме удаления его, если он не является алфавитным), поэтому я делаю строки заглавными tr
в скрипте оболочки.
Этот метод не был тщательно протестирован, но, по-видимому, он правильно обрабатывает имена, упомянутые в статье Википедии.
Аннотированная версия («шаги» относятся к шагам в вышеупомянутой статье Википедии):
# Remove non-alphabetic characters
s/[^[:alpha:]]//g
# STEP 1 (part 1: retain first character)
# Save whole line in hold-space
h
# Delete everything but the first character and swap with hold-space
s/^\(.\).*$/\1/
x
# The hold-space now contains only the first character
# STEP 2
y/bfpvBFPVcgjkqsxzCGJKQSXZdtDTlLmnMNrR/111111112222222222222222333344555566/
# STEP 3
s/\([1-6]\)[hwHW]\1/\1/g
s/\([1-6]\)\1\1*/\1/g
# STEP 1 (part 2: remove vowels etc.)
# We don't actually remove them but "mask" them with "!"
# This avoids accidentally deleting the first character later
s/[aeiouyhwAEIOUYHW]/!/g
# Replace first character with the one saved in the hold-space
# Delete first character
s/^.//
# Append pattern-space to hold-space and swap
H
x
# Remove newline inserted by "H" above and all "!" (old vowels etc.)
s/\n//
s/!//g
# STEP 4
s/^\(....\).*$/\1/
s/^\(...\)$/\10/
s/^\(..\)$/\100/
s/^\(.\)$/\1000/
Поиск с использованием значений Soundex в основном зависит от удачи.
Также:
$ paste <( printf '%s\n' * | sed -f soundex.sed ) <( printf '%s\n' * )
F236 Factorio
F230 Fasta
G500 Game
H265 HackerRank
K200 KEYS
L210 Lisp
P625 Parsing
P315 Pathfinder
P315 Pathfinder.tar.xz
Q000 QA
R165 Reformat
R123 Repositories
R564 RimWorld
S613 Scripts
U523 UNIX.dot
U521 UNIX.png
U523 UNIX.txt
W620 Work
a526 answers.txt
c313 cat-food-schedule.txt
f212 fizzbuzz
f212 fizzbuzz.c
f212 fizzbuzz2
f212 fizzbuzz2.c
p363 poetry.txt
q235 questions.txt
r200 rc
s532 soundex.sed
s532 soundex.sh
u313 utp-1.0.tar.gz