일반 텍스트 마이닝

일반 텍스트 마이닝

(원제: 줄이 아닌 단락 측면에서 grep)

이 질문은 fzf내 거대한 파일 시스템에서 특정 파일을 찾을 수 있게 해주는 에 의해 동기가 부여되었습니다.모호하고 점진적으로, 매우 빠른 검색 경험을 제공합니다(여기서 수많은 귀여운 GIF를 참조하세요).기사).

내가 염두에 두고 있는 것은 내 노트에 대해 비슷한 일을 하는 것입니다. 나는 일반 텍스트 형식으로 된 짧은 메모, 일기, 메모 등을 많이 가지고 있습니다. 을 위한가독성, 각 줄은 72자를 초과할 수 없습니다. 이로 인해 , .. 와 같은 기존 검색 도구에 대한 순진한 지식을 바탕으로 내 노트를 검색하기가 어려워졌습니다 grep.ripgrep

이제 다음을 표시할 수 있습니다(/더 적은) 일치하는 패턴에 대한 컨텍스트이지만 내가 요구하는 것은 아닙니다. 여기에는 좀 더 정확하게 설명하기 위해 예를 포함합니다.

1  Victim mentality is an acquired personality trait in which a person
2  tends to recognize or consider themselves as a victim of the negative
3  actions of others, and to behave as if this were the case in the face
4  of contrary evidence of such circumstances. Victim mentality depends
5  on clear thought processes and attribution.
6
7  (from wikipedia: Victim mentality)

내가 반년 전에 이 메모를 작성했고 그것이 내 파일 시스템 어딘가에 있다는 것을 알았다고 가정해 보겠습니다. 늘 그렇듯이 정확한 단어를 암송할 수는 없지만,우리는 맥락을 기억한다! 내 파일 시스템에 , 또는 grep같은 텍스트를 보내면personalityclear thoughtvictim~도정말 범위를 좁힐 수 있는 관련 항목이 많습니다.

이와 같은 텍스트를 검색하는 데 도움이 되는 도구(기존 여부)가 있어야 합니다.우리의 오래된 노트(일반 텍스트)가 훨씬 더 가치가 있을 것입니다.. 우리의 오랜 친구 grep와 그 친척들 과 함께 할 수 있는 방법이 있을까요 ? 아니면 작동하는 다른 방법이 있습니까? 어떤 의견이라도 높이 평가됩니다.

답변1

(검색) 프로세스를 더 작은 부분으로 나누어 보겠습니다.

먼저 검색하려는 파일 목록을 가져와야 합니다. 예를 들어 현재 디렉터리( .)에서 txt 확장자( -name "*.txt")가 있는 모든 파일은 확실히 파일( -type f)입니다.

find . -name "*.txt" -type f

이 결과는 대/소문자( ) 를 무시하고 출력에 줄 번호와 파일 이름을 포함하여 해당 파일 내부를 grep찾기 위한 입력으로 사용할 수 있습니다. 결국 모든 파일이 한 번에 하나씩 실행되는 것이 아니라 한 번의 실행으로 파악됩니다.something-nHi+

find . -name "*.txt" -type f -exec grep -nHi 'something' {} +

파일 수가 너무 많으면(> $ARG_MAX)+와 함께 \;.

이전 명령의 출력은 다음과 같습니다.

./some/dir/somewhere/songs.txt:128:But had me believing it was always something that I'd done
./some/dir/somewhere/songs.txt:883:Was never something I pursued
./some/dir/somewhere/songs.txt:2905:I know something about love 
./some/dir/somewhere/songs_other.txt:11780:will come across something like this:  F (Dshape).

따라서 해당 줄을 분할하면 :파일 이름, 일치 항목이 발견된 줄 번호 및 줄 자체의 3가지 구성 요소를 얻게 됩니다.

이제 일치하는 모든 파일에 대해 이 정보를 유지하면 다음 용어를 검색하고 일치하는 거리를 합산하여 검색된 용어가 가장 가까운 파일을 찾을 수 있습니다.

예제 텍스트의 경우 3개 용어( personality, clear thought, victim)를 검색하면 해당 줄 번호가 1, 5, 2이므로 이 파일의 거리는 (첫 번째 용어에서 시작)입니다.

abs(1-5) + abs(1-2) = 5 

따라서 모든 용어를 포함하고 해당 파일에서 가장 가까운 용어를 갖는 것에 따라 파일을 정렬할 수 있습니다.

물론 이것은 전체 그림이 아닙니다. 예를 들어 일부 파일에는 동일한 용어가 여러 번 포함되어 있으며 이 알고리즘은 거리를 계산하는 방법을 결정해야 하지만 위에서부터 시작해야 한다고 생각합니다.

답변2

간단한 Perl 한 줄로 작업을 수행할 수 있습니다. 다음은 모든 키워드(예: personalityclear thought및 및 victim)가 파일에 존재하는 경우 "found"가 뒤에 오는 파일 이름을 인쇄합니다.

perl -0777 -ane 'print "$ARGV: found\n" if /^(?=.*personality)(?=.*clear thought)(?=.*victim)/s' file.txt 

산출:

file.txt: found

설명:

-0777       # slurp mode
-ane        # read the file ans execute the following
print "$ARGV: found\n"      # print,$ARGV contains the current filename
if                          # if
  /                         # regex delimiter
    ^                       # begining of file
      (?=.*personality)     # positive lookahead, make sure we have "personality"
      (?=.*clear thought)   # positive lookahead, make sure we have "clear thought"
      (?=.*victim)          # positive lookahead, make sure we have "victim"
  /s                        # regex delimiter, s = dot matches newline

모든 txt 파일을 검색하려면 다음을 사용하세요.perl ...... *.txt

관련 정보