수많은 파일이 포함된 디렉토리가 있습니다. 게다가 정확한 파일명도 잊어버렸어요. 그래서 파일을 찾으려고 해도 찾을 수 없습니다.
검색에 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