Một cách khác để làm tất cả với awk
một mình
$ awk '{words[length()]++} END{for(k in words)print k " character words - " words[k]}' ip.txt
2 character words - 3
5 character words - 1
7 character words - 1
words[length()]++
sử dụng độ dài của dòng đầu vào làm khóa để tiết kiệm số lượng
END{for(k in words)print k " character words - " words[k]}
sau khi tất cả các dòng được xử lý, in nội dung của mảng ở định dạng mong muốn
So sánh hiệu suất, số được chọn là tốt nhất trong hai lần chạy
$ wc words.txt
71813 71813 655873 words.txt
$ perl -0777 -ne 'print $_ x 1000' words.txt > long_file.txt
$ du -h --apparent-size long_file.txt
626M long_file.txt
$ time awk '{words[length()]++} END{for(k in words)print k " character words - " words[k]}' long_file.txt > t1
real 0m20.632s
user 0m20.464s
sys 0m0.108s
$ time perl -lne '$h{length($_)}++ }{ for $n (sort keys %h) {print "$n character words - $h{$n}"}' long_file.txt > t2
real 0m19.749s
user 0m19.640s
sys 0m0.108s
$ time awk '{ print length }' long_file.txt | sort -n | uniq -c | awk '{ printf("%d character words - %d\n", $2, $1) }' > t3
real 1m23.294s
user 1m24.952s
sys 0m1.980s
$ diff -s <(sort t1) <(sort t2)
Files /dev/fd/63 and /dev/fd/62 are identical
$ diff -s <(sort t1) <(sort t3)
Files /dev/fd/63 and /dev/fd/62 are identical
Nếu tệp chỉ có các ký tự ASCII,
$ time LC_ALL=C awk '{words[length()]++} END{for(k in words)print k " character words - " words[k]}' long_file.txt > t1
real 0m15.651s
user 0m15.496s
sys 0m0.120s
Không chắc tại sao thời gian perl
không thay đổi nhiều, có lẽ phải mã hóa theo cách khác