如何在檔案搜尋中使用 soundex 搜尋?

如何在檔案搜尋中使用 soundex 搜尋?

我有一個包含許多文件的目錄。而且,我忘記了確切的檔案名稱。因此,當我想查找文件時卻找不到它。

如果有任何使用 soundex 演算法進行搜尋的工具對我的情況有幫助。

答案1

這是出於我自己的好奇心而寫的答案。您可能應該根據“的答案中的建議來構建一些東西是否有一個 Unix 命令可以主要根據發音時的發音來搜尋相似的字串?「(PerlText::Soundex模組)而不是使用它。


以下 shell 腳本和隨附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

shell 腳本 ( 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 值與搜尋項目匹配,則列印該檔案的完整路徑。

我承認shell腳本有點基礎。例如,可以透過在soundex.sed腳本中新增絕對路徑來改進。如現在所寫的,它要求sed腳本位於當前目錄中。它也不支援包含換行符的檔案名稱。

劇本sedsoundex.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在 shell 腳本中將字串大寫。

這尚未經過徹底測試,但似乎可以正確處理維基百科文章中提到的名稱。

附註解的版本(「步驟」指的是上述維基百科文章中的步驟):

# 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

相關內容