작은 단어 세트(구체성을 위해 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