서로 가까운 단어에 대한 퍼지 검색

서로 가까운 단어에 대한 퍼지 검색

작은 단어 세트(구체성을 위해 3개라고 가정)가 주어지지만 더 일반적으로는 n두 단어가 서로 가까운 상황을 파일에서 검색하고 싶습니다. 근접성 측면에서 두 단어가 최대 k한 문자 떨어져 있다고 가정합니다 k. 여기서 는 상수입니다.

이유: 내 받은편지함( )에서 /var/spool/mail/username특정 키워드가 포함된 특정 이메일을 찾고 있습니다. 이 키워드가 어떻게 생겼는지 잘 모르겠습니다. 그런데 비교적 자주 쓰이는 단어가 하나 있습니다. 두 단어가 서로 매우 가까운 경우는 흔하지 않습니다.

구체적인 동기 부여 사례:

"알루미늄", "수하물", "보관함".

이 경우에는 수하물에 관한 이메일을 검색하고 있습니다.

n와 관련하여 솔루션이 k최고가 될 것입니다.

이를 여러 파일에 적용하는 방법에 대한 몇 가지 지침이 도움이 될 것입니다.

솔루션이 어떤 언어로 되어 있는지는 상관하지 않습니다.

답변1

다음을 고려할 수 있습니다.

1) glark, which has an option:
   ( expr1 --and=NUM expr2 )
   Match both of the two expressions, within NUM lines of each other.

2) bool, with expressions like:
   bool -O0 -C0 -D5 -b "two near three"

3) peg, which accepts options like:
   peg "/x/ and near(sub { /y/ or /Y/ }, 5)"

glark의 코드는 다음 위치에 있습니다.https://github.com/jpace/glark그리고 아마도 일부 저장소에 있을 것입니다.

bool 및 peg에 대한 일부 세부 정보:

bool    print context matching a boolean expression (man)
Path    : ~/executable/bool
Version : 0.2.1
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Help    : probably available with -h,--help
Home    : https://www.gnu.org/software/bool/ (doc)

peg     Perl version of grep, q.v. (what)
Path    : ~/bin/peg
Version : 3.10
Length  : 4749 lines
Type    : Perl script, ASCII text executable
Shebang : #!/usr/bin/env perl
Repo    : Debian 8.9 (jessie) 
Home    : http://piumarta.com/software/peg/ (pm)
Home    : http://www.cpan.org/authors/id/A/AD/ADAVIES/peg-3.10 (doc)

행운을 빕니다... 건배, drl

답변2

다음과 같은 형태소 분석 도구로 시작하세요. https://linux.die.net/man/1/hunspell 그런 다음 정규식을 사용하십시오. https://linux.die.net/man/1/grep 그런 다음 wc sort 및 Unique를 사용하여 단어 근접성을 기준으로 정렬합니다.

의사 배쉬;

WORDS=$1
HAYSTACK=/var/mail

STEMS=$(hunspell --stem $WORDS)
REGEX=$(echo $STEMS | perl -pe 's/ /.*/g')
while read MATCH ; do
    FILE=$(echo $MATCH | cut -d : 1)
    COUNT=$(echo $MATCH | cut -d : 2 | perl -pe 's/.*('"$REGEXX"').*/$1/g' | wc -c)
    echo $COUNT\t$FILE
done < <(grep -rP "$REGEX" $HAYSTACK) | \
sort -nr

더 빠르게 원하시면 사용하셔도 됩니다 https://linux.die.net/man/1/locate 정규 표현식을 사용하여 단어 사이의 공백을 제한하세요.

a.{1,50}b

답변3

나는 이 아이디어를 좋아한다grep 메일(저희 가게에서는 rapgrep이라는 유틸리티를 작성했는데,모든 모드가 필요합니다, 일반적인 경우).

이 스니펫은 국가, 사람, 시간이라는 단어를 찾아 문자 거리 측면에서 보다 구체적인 답변을 보여줍니다.

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
pl " Input data file $FILE:"
head $FILE

pl " Results, egrep:"
egrep 'time|men|country' $FILE

pl " Results, egrep, with byte offset:"
egrep -b 'time|men|country' $FILE

pl " Results, egrep, with byte offset, matches only:"
egrep -o -b 'time|men|country' $FILE |
tee t1

pl " Looking for minimum distance between all pairs:"

awk -F":" '
  { a[$2] = $1  # Compare every item to the new item
    for ( b in a ) {
      for ( c in a ) {
      # print " Working on b = ",b," c = ",c
        if ( b != c ) {
        v0 = a[c]-a[b]
        v1 = v0 < 0 ? -v0 : v0  # convert to > 0
        v2 = (b < c) ? b " " c : c " " b  # trivial sort of names
        print v1, v2
      }
    }
    }
  }

' t1 |
datamash -t" " -s --group 2,3 min 1 

생산:

-----
 Input data file data1:
Now is the time
for all good men
to come to the aid
of their country.

-----
 Results, egrep:
Now is the time
for all good men
of their country.

-----
 Results, egrep, with byte offset:
0:Now is the time
16:for all good men
52:of their country.

-----
 Results, egrep, with byte offset, matches only:
11:time
29:men
61:country

-----
 Looking for minimum distance between all pairs:
country men 32
country time 50
men time 18

그리고 특정 단어가 여러 번 나타나는 약간 더 복잡한 파일은 다음과 같습니다.

-----
 Input data file data2:
Now is the time men
for all good men
to come to the aid
of their men country.

-----
 Results, egrep:
Now is the time men
for all good men
of their men country.

-----
 Results, egrep, with byte offset:
0:Now is the time men
20:for all good men
56:of their men country.

-----
 Results, egrep, with byte offset, matches only:
11:time
16:men
33:men
65:men
69:country

-----
 Looking for minimum distance between all pairs:
country men 4
country time 58
men time 5

이는 GNU grep의 바이트 수 옵션을 활용하고 awk 프로그램은 단어 쌍 사이의 모든 거리를 계산하고 마지막으로 datamash가 가장 작은 거리를 정렬, 그룹화 및 선택합니다.

명령줄에 단어를 허용하고 거리를 허용하도록 매우 쉽게 매개변수화할 수 있습니다. awk 프로그램에서 datamash로의 입력 데이터 형식에 대한 설명은 파일 t1을 참조하세요.

다음 시스템에서 실행됩니다.

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30
grep (GNU grep) 2.20
awk GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2-p3, GNU MP 6.0.0)
datamash (GNU datamash) 1.2

행운을 빕니다... 건배, drl

관련 정보