![중복 행의 대소문자를 구분하지 않고 계산, 중복 수가 가장 많은 대소문자를 선택하여 중복 제거](https://linux55.com/image/67114/%EC%A4%91%EB%B3%B5%20%ED%96%89%EC%9D%98%20%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%EB%A5%BC%20%EA%B5%AC%EB%B6%84%ED%95%98%EC%A7%80%20%EC%95%8A%EA%B3%A0%20%EA%B3%84%EC%82%B0%2C%20%EC%A4%91%EB%B3%B5%20%EC%88%98%EA%B0%80%20%EA%B0%80%EC%9E%A5%20%EB%A7%8E%EC%9D%80%20%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%EB%A5%BC%20%EC%84%A0%ED%83%9D%ED%95%98%EC%97%AC%20%EC%A4%91%EB%B3%B5%20%EC%A0%9C%EA%B1%B0.png)
복사는 다른 대소문자의 텍스트 조합입니다.
중복 항목 수를 계산해야 하며(대소문자 구분 안 함), 중복 항목이 가장 많은 사례를 선택하여 중복 항목을 제거해야 합니다.
아래 예:
hot chocolate
hot chocolate
hot chocolate
Hot Chocolate
Hot Chocolate
Hot Chocolate
Hot Chocolate
Hot Chocolate
Xicolatada
Xicolatada
Xicolatada
Xicolatada
XICOLATADA
XICOLATADA
다음과 같아야 합니다:
Hot Chocolate, 8
Xicolatada, 6
이 질문은 다음과 유사합니다.이것하지만 가장 많이 반복되는 사례를 선택하고 대소문자를 구분하여 계산해야 합니다.
답변1
게다가 uniq --ignore-case --count | sort --numeric --reverse
:
sort | uniq -ic /tmp/foo.txt | sort -nr
8 hot chocolate
6 Xicolatada
순서를 바꾸려면 거기에 쉼표를 추가하고 끝에 이 파이프를 추가하세요.
... | sed -e 's/^ *\([0-9]*\) \(.*\)/\2, \1/'
왜 선행 정렬이 있는지 알아보려면 아래 첫 번째 설명을 참조하세요.
답변2
tolower()
나는 모든 항목을 소문자로 만드는 데 사용합니다 . 그런 다음 배열에 저장 a[]
하고 결과를 인쇄합니다.
$ awk '{a[tolower($0)]++} END {for (i in a) print i, a[i]}' file
xicolatada 6
hot chocolate 8
쉼표로 구분된 형식으로 출력하려면 -v OFS=,
.
답변3
그러면 원하는 출력이 제공됩니다.
use List::Util qw(sum);
my %count;
while (<>) {
chomp;
$count{+lc}{$_}++;
}
$,=", ";
$\="\n";
while (my ($key, $hash) = each %count) {
my @labels = reverse
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, $hash->{$_} ] }
keys %$hash;
my $sum = sum values %$hash;
print $labels[0], $sum;
}
그 다음에
$ perl count.pl data.txt
Hot Chocolate, 8
Xicolatada, 6
출력 순서는 정의되지 않습니다.
답변4
POSIX적으로:
<in dd conv=lcase|LC_ALL=C sort|uniq -c >out
...인쇄...
8 hot chocolate
6 xicolatada
또는 GNU 도구를 사용하십시오.
<in LC_ALL=C sort -f|uniq -ic >out
...인쇄...
8 Hot Chocolate
6 XICOLATADA
GNU가 필요합니다. uniq
또는 어쨌든 -i
대소문자를 구분하지 않는 옵션을 지원하는 GNU가 필요합니다. 어쨌든 모두가 sort
그렇게 해야 합니다 -f
.