나는 다음 요구 사항에 따라 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
...