다음과 같은 텍스트 파일이 있습니다.
tom
and
jerry
went
to
america
and
england
각 단어가 얼마나 자주 나타나는지 알고 싶습니다.
다음 명령을 시도하면
cat test.txt |sort|uniq -c
나는 다음과 같은 결과를 얻습니다.
1 america
2 and
1 england
1 jerry
1 to
1 tom
1 went
하지만 부분 일치도 필요합니다. 즉, to
단어에 나타나는 단어 입니다 tom
. 그래서 내 예상 단어 수 to
는 2입니다. unix
명령을 사용할 수 있나요 ?
답변1
다음은 방법이지만 매우 우아하지는 않습니다.
$ sort -u file | while IFS= read -r word; do
printf '%s\t%s\n' "$word" "$(grep -cFe "$word" file)";
done
america 1
and 3
england 1
jerry 1
to 2
tom 1
went 1
답변2
떨어져 awk
있는:
awk '
!x {c[$0]; next}
{for (i in c) if (index($0, i)) c[i]++}
END{for (i in c) print c[i]"\t"i}' file x=1 file | sort -k1rn
귀하의 의견은 무엇을 제공합니까?
3 and
2 to
1 america
1 england
1 jerry
1 tom
1 went
우리는 입력을 두 단계로 처리합니다. 첫 번째 단계에서는 다양한 단어 목록을 c
해시 테이블의 키로 기록합니다.
두 번째 패스에서는 파일의 각 라인에 대해 모든 키를 반복하고 c
해당 라인에서 키가 발견되면 해당 값을 증가시킵니다.
파일의 다른 단어 목록은 결국 메모리에 저장됩니다. 이것이 영어 단어라면, 영어에는 200,000개 미만의 다른 단어가 있기 때문에 문제가 되지 않습니다.
답변3
시스템이 충돌하지는 않지만 입력을 여러 번 구문 분석하므로 실행하는 데 오랜 시간이 걸릴 수 있습니다. 입력 파일 이름이 "in"이라고 가정합니다.
sort -u < in | while read w
do
printf "%d\t%s\n" `grep -c "$w" in` "$w"
done
귀하의 의견을 통해 다음을 수행할 수 있습니다.
1 america
3 and
1 england
1 jerry
2 to
1 tom
1 went
답변4
부분 일치가 줄의 시작 부분에 고정되는지 여부가 명확하지 않습니다. 대답이 '예'라고 가정하면 어떻게 될까요?가능한여기서 속도를 높이는 방법은 Ancient 명령을 통해 이진 검색을 사용하는 것입니다 look
. 물론 look
입력 파일을 정렬해야 합니다. 먼저 원본 파일의 정렬된 버전을 만듭니다.
sort file > file.sorted
그런 다음 원본 파일을 반복하면서 look
정렬된 파일에 대해 한 번에 한 단어씩 찾습니다.
while read -r word; do
printf "%s %d\n" "$word" "$(look -b "$word" file.sorted | wc -l)";
done <file
일부 시스템에서는 이진 검색을 강제하기 위해 -b
플래그를 전달할 필요가 없습니다 . look
정렬된 파일의 디스크 캐싱은 작업 속도를 더욱 높이는 데 도움이 될 수 있습니다.