저는 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
예제는 조립 후, 파이핑 전의 모습은 다음과 같습니다 .paste
sort
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