ファイル検索でsoundex検索を使用するには?

ファイル検索でsoundex検索を使用するには?

多くのファイルを含むディレクトリがあります。そして正確なファイル名を忘れましたね。だから、あなたがファイルを見つけたいと思っても見つかりません。

私の場合は、soundexアルゴリズムを使用して検索するツールが役に立ちます。

答え1

私の好奇心で書いた答えです。おそらく、次の答えの提案に基づいて何かを構築する必要があります。主に、発音方式に基づいて類似した文字列を検索できるUnixコマンドはありますか?「(PerlText::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スクリプトは現在のディレクトリになければなりません。また、改行文字を含むファイル名もサポートされていません。

スクリプト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/

これが「アメリカンサウンデックス」を実現する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

関連情報