fgrep/Ag에서 검색 속도를 높이는 방법은 무엇입니까?

fgrep/Ag에서 검색 속도를 높이는 방법은 무엇입니까?

fgrep주로 또는 를 사용하여 검색을 더 빠르고/또는 더 좋게 만드는 방법을 생각하고 있습니다 ag. and대소문자를 구분하지 않고 단어를 검색 $HOME하고 일치 항목 목록을 다음으로 리디렉션하는 코드입니다.vim

find -L $HOME -xtype f -name "*.tex" \
   -exec fgrep -l -i "and" {} + 2>/dev/null | vim -R -

ag병렬성 과ack

find -L $HOME -xtype f -name "*.tex" \
   -exec ag -l -i "and" {} + 2>/dev/null | vim -R -

통계자료

그룹 평균 fgrep통계agtime

        fgrep   ag     terdon1  terdon2  terdon3  muru 
user    0.41s   0.32s  0.14s    0.22s    0.18s    0.12s
sys     0.46s   0.44s  0.26s    0.28s    0.30s    0.32s

예제 terdon1terdon3똑같이 빠를 수 있습니다. 이 두 사람을 대하는 나의 태도는 크게 변한다. 시간별 일부 순위 sys(최고의 기준은 아님!)

  1. 테든 1
  2. 테든 2
  3. 테톤 3
  4. 무루
  5. 주식회사
  6. 명령줄 도구

약어

  • terdon1 = terdon-many-find-grep
  • terdon2 = terdon-many-find-fgrep
  • terdon3 = terdon-many-find-ag (F가 없기 때문에 F가 없음 ag)

다른 코드

댓글에 있는 무루의 제안

grep -RFli "and" "$HOME" --include="*.tex" | vim -R -

운영 체제: Debian 8.5
하드웨어: ASUS Zenbook UX303UA

답변1

ackThe Silver Searcher( ) 를 사용하고 계시기 때문에 ag다른 도구를 사용하셔도 될 것 같습니다.

이 영역의 새로운 도구는 ripgrep( rg)입니다. 그것은 빠르게 설계되었습니다발견하다검색할 파일(예 ag:)도 빠릅니다.찾다파일 자체 (평범한 오래된 GNU 와 같습니다 grep).

귀하의 질문에 대한 예를 들어 다음과 같이 사용할 수 있습니다.

rg --files-with-matches --glob "*.tex" "and" "$HOME"

ripgrep의 저자공개된 상세 분석다양한 검색 도구의 작동 방식 및 벤치마크 비교.

벤치마크 중 하나는,linux-literal-casei, 귀하가 설명하는 작업과 다소 유사합니다. 다수의 중첩된 디렉터리(Linux 코드 기반)에서 다수의 파일을 검색하여 대소문자를 구분하지 않는 문자열 리터럴을 검색합니다.

이 벤치마크에서는 rg화이트리스트(예: "*.tex" 예)를 사용할 때 가장 빠릅니다. 이 ucg도구는 이 벤치마크에서도 좋은 성능을 발휘합니다.

rg (ignore)         0.345 +/- 0.073 (lines: 370)
rg (ignore) (mmap)  1.612 +/- 0.011 (lines: 370)
ag (ignore) (mmap)  1.609 +/- 0.015 (lines: 370)
pt (ignore)        17.204 +/- 0.126 (lines: 370)
sift (ignore)       0.805 +/- 0.005 (lines: 370)
git grep (ignore)   0.343 +/- 0.007 (lines: 370)
rg (whitelist)      0.222 +/- 0.021 (lines: 370)+
ucg (whitelist)     0.217 +/- 0.006 (lines: 370)* 

* - 최고의 평균 시간. + - 최적의 샘플링 시간.

저자는 ack이 테스트가 다른 테스트보다 훨씬 느리기 때문에 벤치마크에서 제외했습니다.

답변2

find여러 호출을 병렬로 실행하면 조금 더 빠르게 만들 수 있습니다. 예를 들어, 먼저 모든 최상위 디렉토리를 가져오고 각 디렉토리에 하나씩 N개의 찾기 호출을 실행합니다. 서브셸에서 실행 중인 경우 출력을 수집하여 vim 등으로 파이프할 수 있습니다.

shopt -s dotglob ## So the glob also finds hidden dirs
( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done
) | vim -R -

또는 모든 조회가 완료된 후에만 출력을 받기 시작하는지 확인하세요.

( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done; wait
) | vim -R -

몇 가지 테스트를 해본 결과 위의 테스트는 실제로 단일 테스트보다 약간 빠릅니다 find. 평균적으로 10회가 넘는 실행, find도구의 단일 호출에 0.898초가 걸렸고, 위의 하위 셸은 디렉터리당 조회를 실행하는 데 0.628초가 걸렸습니다.

세부 사항은 항상 가지고 있는 디렉터리 수 $HOME, 파일을 포함할 수 있는 디렉터리 수 .tex, 일치할 수 있는 디렉터리 수에 따라 달라지므로 상황이 다를 수 있습니다.

관련 정보