한 줄에 문자가 나타나는 횟수를 기준으로 파일을 정렬하는 방법은 무엇입니까?

한 줄에 문자가 나타나는 횟수를 기준으로 파일을 정렬하는 방법은 무엇입니까?

저는 Linux를 처음 접했고 파일에서 문자 계산을 수행하는 방법에 대한 유용한 정보를 많이 찾았지만 Linux/터미널에 문자가 나타나는 특정 횟수에 따라 텍스트 파일을 정렬하는 방법이 있습니까? 선?

예를 들어 다음과 같습니다.

baseball
aardvark
a man a plan a canal panama
cat
bat
bill

문자 "a"가 나타나는 횟수를 기준으로 정렬하면 다음과 같은 결과를 얻습니다.

a man a plan a canal panama
aardvark
baseball
cat
bat
bill

"a"가 각각 한 번 나타나는 "cat"과 "bat"에 대해서는 동일한 개수의 줄 순서가 바뀌어도 상관 없으며 문자 빈도에 따른 일반적인 줄 순서만 적용됩니다.

답변1

이러한 작업에 대한 일반적인 접근 방식은 awk또는 perl...를 사용하여 관심 있는 측정항목을 계산하고 행 앞에 추가한 다음 이를 정렬된 출력에 제공 sort하고 정렬된 출력에서 ​​측정항목을 제거하는 것입니다.

awk '{print gsub("a","a"), $0}' < file | sort -rn | cut -d' ' -f2-

답변2

또 다른 Schwartz 변환:

$ awk -Fa '{print NF,$0}' file | sort -nr | cut -d' ' -f2-
a man a plan a canal panama
aardvark
baseball
cat
bat
bill

또는 Perl에서는:

perl -Fa -lane 'print "$#F $_"' file | sort -nr | cut -d' ' -f2-

답변3

문자만을 기준으로 정렬할 수도 있습니다.

tr -cd a\\n <file | paste - ./file | LC_ALL=C sort -rk1,1 | cut -f2-

tr예제는 조립 후, 파이핑 전의 모습은 다음과 같습니다 .pastesort

aa  baseball
aaa aardvark
aaaaaaaaaa  a man a plan a canal panama
a   cat
a   bat
    bill

그런 다음 sort그것을 얻고 모든 것이 동일하다면 더 긴 키보다 짧은 키를 정렬하지만 -r그 반대의 경우 출력은 다음과 같습니다.

aaaaaaaaaa  a man a plan a canal panama
aaa aardvark
aa  baseball
a   cat
a   bat
    bill

... cut첫 번째 탭만 삭제하세요.

a man a plan a canal panama
aardvark
baseball
cat
bat
bill

답변4

Schwartzian 변환이 언급된 이후로 아직까지 이에 대한 순수한 Perl 구현을 게시한 사람이 없다는 사실에 놀랐습니다.

perl -ne 'push @a, $_ }{ print map { $_->[0] } sort { $b->[1] <=> $a->[1] } map { [$_, $_ =~ tr/a//] } @a' file
a man a plan a canal panama
aardvark
baseball
cat
bat
bill

파일의 각 줄은 에 푸시된 @a다음 파일을 읽고 나면 a문자 수를 사용하여 배열이 정렬됩니다.

문자 발생 횟수를 세는 것은 계산 비용이 많이 드는 함수가 아니므로 정렬만 사용하는 것이 더 깔끔한 접근 방식입니다.

$ perl -ne 'push @a, $_ }{ print sort { $b =~ tr/a// <=> $a =~ tr/a// } @a' file
a man a plan a canal panama
aardvark
baseball
cat
bat
bill

관련 정보