파일 검색에서 soundex 검색을 사용하는 방법은 무엇입니까?

파일 검색에서 soundex 검색을 사용하는 방법은 무엇입니까?

수많은 파일이 포함된 디렉토리가 있습니다. 게다가 정확한 파일명도 잊어버렸어요. 그래서 파일을 찾으려고 해도 찾을 수 없습니다.

검색에 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" {} +

sed스크립트는 아래 스크립트를 사용하여 검색어에 대한 soundex 값을 계산합니다 . 그런 다음 현재 디렉토리 또는 그 이하의 모든 이름을 찾는 데 사용 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"를 구현합니다.Wikipedia에 설명된 대로. 초기 문자를 수정하지 않습니다(알파벳이 아닌 경우 삭제하는 것은 제외). 이것이 tr쉘 스크립트에서 문자열을 대문자로 바꾸는 이유입니다.

이는 철저히 테스트되지 않았지만 Wikipedia 기사에 언급된 이름을 올바르게 처리하는 것 같습니다.

주석이 달린 버전("단계"는 위에 언급된 Wikipedia 문서의 단계를 나타냄):

# 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

관련 정보