(원제: 줄이 아닌 단락 측면에서 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
같은 텍스트를 보내면personality
clear thought
victim
~도정말 범위를 좁힐 수 있는 관련 항목이 많습니다.
이와 같은 텍스트를 검색하는 데 도움이 되는 도구(기존 여부)가 있어야 합니다.우리의 오래된 노트(일반 텍스트)가 훨씬 더 가치가 있을 것입니다.. 우리의 오랜 친구 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 한 줄로 작업을 수행할 수 있습니다. 다음은 모든 키워드(예: personality
및 clear 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