현재 디렉토리의 모든 파일에서 용어의 모든 발생을 어떻게 계산합니까?


10

현재 디렉토리의 모든 파일에서 용어의 모든 발생을 어떻게 계산합니까? -및 서브 디렉토리 (?)

나는 당신이 이것을 사용하기 위해 그것을 읽었습니다 grep. 정확한 명령은 무엇입니까?

또한 다른 명령으로 위의 작업이 가능합니까?

답변:


12

grep+를 사용하면 wc(동일한 줄에 여러 단어가 나타나는 경우)

grep -rFo foo | wc -l
  • -rin grep: 현재 디렉토리 계층에서 재귀 적으로 검색합니다.
  • -Fin grep: 패턴 대신 고정 문자열과 일치합니다.
  • -oin grep: 일치 만 인쇄합니다.
  • -lin wc: 줄 수를 인쇄합니다.
% tree                 
.
├── dir
│   └── file2
└── file1

1 directory, 2 files
% cat file1 
line1 foo foo
line2 foo
line3 foo
% cat dir/file2 
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8

가장 좋은 것 같아요.
Jacob Vlijm

1
트윗 담아 가기 나도 너를 좋아해 (그리고 이미 찬성했다)
kos

나는 PCREs그들이 실험적이기 때문에 사용해서는 안된다고 생각합니다
Edward Torvalds

2
PCRE는 "실험적"이 아니지만 항상 grep으로 컴파일되는 것은 아닙니다 (그래서 필요할 때 pcregrep을 사용합니다). 그러나이 질문은 어떤 종류의 패턴이 아니라 고정 문자열 일 가능성이있는 "term"에 대해 질문하기 때문에 불필요합니다. 따라서 -F아마도 더 빠를 것입니다.
dannysauer

2
@ dannysauer 나는 PCRE를 사용했습니다. 왜냐하면 어떤 이유로 (같은 이유로) 같은 줄에서 여러 번 발생하는 것을 일치 시켜야 한다고 생각했기 때문입니다 . 그러나 실제로는 그렇지 않습니다. 방금 -F대신을 사용하지 않았습니다 -P. 를 사용하여 업데이트하는 큰 제안에 감사드립니다 -F. 실제로 여기에 더 적합합니다.
kos

8

grep -Rc [term] *그렇게 할 것입니다. -R플래그는 재귀 적으로 현재 디렉토리와 모든 서브 디렉토리를 검색 할 의미합니다. 는 *모든 파일 : 파일 선택 의미입니다. -c플래그하게 grep출력을 발생의 수를. 그러나 단어가 한 줄에 여러 번 나타나는 경우 한 번만 계산됩니다.

보낸 사람 man grep:

  -r, --recursive
          Read all files under each directory, recursively, following symbolic links only if they are on the command line.
          This is equivalent to the -d recurse option.

   -R, --dereference-recursive
          Read all files under each directory, recursively.  Follow all symbolic links, unlike -r.

디렉토리에 기호 링크가 없으면 차이가 없습니다.


-c플래그를 추가 할 수 있습니다 grep. 그런 다음 grep 자체를 계산하고 필요하지 않습니다wc
Wayne_Yux

당신은 넣어 싶어 수도 --이전*
에드워드 토발즈

2
*비 도트 파일로만 확장되므로 모든 것을 놓칠 수 있습니다. "."만 사용하는 것이 더 합리적입니다. 어쨌든 인수를 재귀 적으로 처리하기 때문에 도트 파일을 얻습니다. 여기서 더 큰 문제는 단어의 수가 아니라 줄의 수가 될 수 있다는 것입니다. 용어가 한 줄에 여러 번 나타나는 경우, 그것은 단지 "그렙 -c"한 번 계산됩니다
dannysauer

2

작은 파이썬 스크립트에서 :

#!/usr/bin/env python3
import os
import sys

s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
    for f in files:
        f = root+"/"+f      
        try:
            n = n + open(f).read().count(s)
        except:
            pass
print(n)
  • 로 저장하십시오 count_string.py.
  • 다음 명령 을 사용하여 디렉토리에서 실행하십시오 .

    python3 /path/to/count_string.py <term>
    

메모

  • 용어에 공백이 있으면 따옴표를 사용하십시오.
  • 한 줄에 여러 번 나타나는 경우에도 재귀 적으로 모든 항목을 계산합니다.

설명:

# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0 
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
    for f in files:
        # join the path(s) above the file and the file itself
        f = root+"/"+f
        # try to read the file (will fail if the file is unreadable for some reason)
        try:
            # add the number of found occurrences of <term> in the file
            n = n + open(f).read().count(s)
        except:
            pass
print(n)

2
python guy ;) +1
TellMeWhy

1
무엇 root과 무엇 f입니까?
TellMeWhy

1
root현재 디렉토리의 "위"를 포함하여 파일의 경로 f이며 파일입니다. 또는 os.path.join()사용할 수 있지만 더 장황합니다.
Jacob Vlijm 2016

1
그리고 n = n + open(f).read().count(s)?
TellMeWhy

2
이것은 OP가 요청한 용어의 모든 항목 을 계산하는 유일한 대답 인 것 같습니다 . AFAIK에서 grep을 사용하는 모든 솔루션은 용어가 발생하는 모든 행을 계산하므로 용어를 3 번 ​​포함하는 행은 한 번만 계산됩니다.
Joe

2

@kos의 좋은 대답의 변형으로, 개수를 항목별로 분류하려면 grep의 -c스위치를 사용 하여 발생 횟수를 계산할 수 있습니다.

$ grep -rFoc foo
file1:3
dir/file2:3
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.