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

이 스크립트는 스크립트(아래)를 사용하여 검색어의 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/

이것이 "아메리칸 사운덱스"를 실현한다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

관련 정보