我有一個包含許多文件的目錄。而且,我忘記了確切的檔案名稱。因此,當我想查找文件時卻找不到它。
如果有任何使用 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
腳本位於當前目錄中。它也不支援包含換行符的檔案名稱。
劇本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
在 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