파일에서 고유한 단어와 해당 개수를 얻고 싶습니다. 다음 명령을 실행하면
sort words.txt | uniq -c
2 america
4 and
1 england
1 file
1 for
1 place
하지만 다음 형식으로 출력을 원합니다.
america,2
and,4
england,1
file,1
for,1
place,1
내 입력 파일은 약 30-40Gb입니다. 그렇다면 이 형식으로 출력을 인쇄하는 가장 좋은 방법은 무엇입니까?
답변1
awk
명령 끝에 줄을 추가 할 수 있습니다 . 예를 들어,
sort words.txt | uniq -c | awk '{print $2","$1}'
기본적으로 첫 번째 열 앞에 두 번째 열을 쉼표로 구분하여 배치합니다. 30-40Gb 파일에서 이것을 실행하는 데 비용이 얼마나 드는지 모르겠습니다.
답변2
awk 자체를 사용하여 이를 수행할 수 있습니다...
아래에서 시도해 보세요.
awk '{j[$0]++} END {for (i in j) print i","j[i]}' words.txt
답변3
그리고 sed
:
sort words.txt | uniq -c | sed -E 's/^ *([0-9]) (.+)/\2,\1/g'
GNU, Busybox 및 BSD 구현으로 테스트되었습니다 sed
. 출력은 다음과 같습니다:
america,2
and,4
england,1
file,1
for,1
place,1
200MB 파일에서 테스트한 결과 sed
자체적으로는 여전히 꽤 빠른 것으로 나타났습니다.
$ time sed -E 's/^ *([0-9]) (.+)/\2,\1/g' HUGE | head
america,2
and,4
england,1
file,1
for,1
place,1
america,2
and,4
england,1
file,1
real 0m0.006s
user 0m0.003s
sys 0m0.006s
-i
그러나 이 두 가지 옵션을 사용하고 >
셸 연산자를 사용하여 출력을 리디렉션하면 데이터를 디스크의 파일에 저장하는 데 많은 시간이 걸립니다.
$ time sed -i -E 's/^ *([0-9]) (.+)/\2,\1/g' HUGE
real 0m45.793s
user 0m31.965s
sys 0m13.574s
$ time sed -E 's/^ *([0-9]) (.+)/\2,\1/g' HUGE > HUGE_NO_I
real 0m29.016s
user 0m28.684s
sys 0m0.119s