매우 큰 파일에서 고유한 단어 발생을 얻는 방법은 무엇입니까?

매우 큰 파일에서 고유한 단어 발생을 얻는 방법은 무엇입니까?

나는 다음 요구 사항에 따라 unix/shell 스크립트를 사용하여 단어 빈도 분석 프로그램을 작성해 달라는 요청을 받았습니다.

  • 입력은 한 줄에 한 단어로 구성된 텍스트 파일입니다.
  • 입력 단어는 New Compact Oxford English Dictionary에서 가져왔습니다.
  • 문자 인코딩은 UTF-8입니다.
  • 입력 파일의 길이는 1페비바이트(PiB)입니다.
  • 출력 형식은 "단어가 N 번 나타납니다"입니다.

시작하는 한 가지 방법은 다음과 같습니다. --- cat filename | xargs -n1 sort |

성능을 고려할 때 가장 좋은 최적의 접근 방식은 무엇입니까?

답변1

알아채다:

오픈소스이긴 하지만 유료 제품이므로 무료로 직접 설치하고 실행할 수 있습니다. 그러나 원하는 경우 무료 평가판을 통해 클라우드에서 테스트해 볼 수 있습니다. 반드시 계정을 구매하기를 바라는 것은 아니지만 매우 큰 텍스트 파일의 데이터를 처리해야 하는 경우 Manta가 완벽하게 처리합니다.

또한 저는 이 제품을 판매하는 조이언트(Joyent)에서 근무하고 있으므로 제 의견은 일말의 의미로 받아들이시기 바랍니다. 하지만 직접 제품을 사용해 보시고 스스로 입증해 보시길 권합니다.

조이언트객체 스토리지만타 레이대량의 데이터 입력을 처리하고 시스템에서 이에 대한 계산을 실행하는 데 적합합니다.

만타의 목적은넓은그러나 나는 귀하의 질문에 특별한 관심을 기울일 것입니다.

데이터에 대한 계산 실행

일부 데이터세트를 업로드하세요.

$ curl -sL http://www.gutenberg.org/ebooks/1661.txt.utf-8 | \
    mput -H 'content-type: text/plain' ~~/stor/books/sherlock_holmes.txt
$ curl -sL http://www.gutenberg.org/ebooks/76.txt.utf-8 | \
    mput -H 'content-type: text/plain' ~~/stor/books/huck_finn.txt
$ curl -sL http://www.gutenberg.org/ebooks/2701.txt.utf-8 | \
    mput -H 'content-type: text/plain' ~~/stor/books/moby_dick.txt
$ curl -sL http://www.gutenberg.org/ebooks/345.txt.utf-8 | \
    mput -H 'content-type: text/plain' ~~/stor/books/dracula.txt

데이터에 대한 작업 실행

다음은 Dracula에서 "vampire"라는 단어가 나타나는 횟수를 계산하는 샘플 과제입니다.

$ echo ~~/stor/books/dracula.txt | mjob create -o -m "grep -ci vampire"
added 1 input to 7b39e12b-bb87-42a7-8c5f-deb9727fc362
32

이 명령은 각 입력 개체에 대해 사용자 스크립트를 실행하는 작업을 생성하며 grep -ci vampire, 이 개체는 ~~/stor/books/dracula.txt작업의 유일한 입력으로 제출됩니다. 작업 이름은 (이 예에서는) 입니다 7b39e12b-bb87-42a7-8c5f-deb9727fc362. 작업이 완료되면 결과가 출력 개체에 저장되며 mjob outputs다음 명령을 사용하여 볼 수 있습니다.


유사한 호출을 사용하여 아래의 모든 개체에 대해 동일한 작업을 실행할 수 있습니다. ~~/stor/books:

$ mfind -t o ~~/stor/books | mjob create -o -m "grep -ci human"
added 5 inputs to 69219541-fdab-441f-97f3-3317ef2c48c0
13
48
18
4
6

이 예에서 시스템은 5번의 호출을 실행합니다 grep. 이들 각각을 작업이라고 합니다. 각 작업은 하나의 출력을 생성하고 작업 자체는 궁극적으로 5개의 별도 출력을 생성합니다.


매핑 및 축소 단계

우리는 전통적인 맵 축소 계산의 "매핑" 단계를 방금 설명했습니다. "매핑" 단계에서는 각 입력 개체에 대해 동일한 계산을 수행합니다. 감소 단계는 일반적으로 맵 단계의 출력을 결합하여 단일 출력을 생성합니다.


초기 예에서는 각 책에 "인간"이라는 단어가 나타나는 횟수를 계산했습니다. 축소 단계에서 간단한 스크립트를 사용 하여 awk모든 책에 "사람"이 나타나는 총 횟수를 얻을 수 있습니다.

$ mfind -t o ~~/stor/books | \
        mjob create -o -m "grep -ci human" -r "awk '{s+=\$1} END{print s}'"
added 5 inputs to 12edb303-e481-4a39-b1c0-97d893ce0927
89

작업에는 두 단계가 있습니다. 맵 단계는 grep -ci human각 입력 객체에서 실행되고, 축소 단계는 awk첫 번째 단계의 연결된 출력에서 ​​스크립트를 실행합니다. awk '{s+=$1} END {print s}'숫자 목록을 합산하므로 첫 번째 단계에서 파생된 숫자 목록을 합산합니다. 여러 맵을 결합하고 단계를 줄일 수 있습니다. 최종 단계가 아닌 모든 단계의 출력은 다음 단계의 입력이 되고, 최종 단계의 출력은 작업 출력이 됩니다.


정확히 무엇을 찾고 있는지 잘 모르겠지만 이것은 귀하의 질문에 있는 명령에 더 가깝습니다.

echo ~~/stor/books/dracula.txt | mjob create -o -m "cat" -r "tr -s '[:blank:]' '[\n*]'" -r "sort" -r "uniq -c" >./tmp/test.txt

산출

   2559
      1 "'Are
      1 "'E's
      1 "'I
      1 "'Ittin'
      1 "'Little
      1 "'Lucy,
      1 "'Maybe
      1 "'Miss
      2 "'My
      1 "'Never
      1 "'No'
      1 "'Ow
      1 "'Silence!
      1 "'That's
      1 "'Tyke
      1 "'Wilhelmina'--I
      1 "'Yes,
      8 "A
      ...

관련 정보