![고유한 값을 계산하고 결과 값을 새 열로 추가합니다.](https://linux55.com/image/216027/%EA%B3%A0%EC%9C%A0%ED%95%9C%20%EA%B0%92%EC%9D%84%20%EA%B3%84%EC%82%B0%ED%95%98%EA%B3%A0%20%EA%B2%B0%EA%B3%BC%20%EA%B0%92%EC%9D%84%20%EC%83%88%20%EC%97%B4%EB%A1%9C%20%EC%B6%94%EA%B0%80%ED%95%A9%EB%8B%88%EB%8B%A4..png)
대용량 csv 파일이 있고 간단한 순위를 작성하고 싶습니다.
$ cat file.csv
2022-12-01 RED 1
2022-12-01 RED 1
2022-12-01 RED 2
2022-12-01 RED 2
2022-12-01 RED 2
2022-12-01 YELLOW 1
2022-12-01 YELLOW 1
2022-12-01 YELLOW 2
2022-12-01 YELLOW 2
2022-12-01 YELLOW 2
$ sort file.csv | uniq -c | sort -nr > file_sort.csv
$ cat file_sort.csv
3 2022-12-01 RED 2
3 2022-12-01 YELLOW 2
2 2022-12-01 RED 1
2 2022-12-01 YELLOW 1
결과를 새 열로 추가하고 싶지만 다음과 같이 기존 $1에 추가하고 싶습니다.
$ cut -f1 file_sort.csv
3 2022-12-01
3 2022-12-01
2 2022-12-01
2 2022-12-01
uniq 행의 값을 새 열로 저장하는 방법이 있나요? 이와 같이:
$ cut -f1 file_sort.csv
3
3
2
2
답변1
당신이 원하는 것은 첫 번째 필드에서 마지막 필드로 숫자를 이동하는 것뿐입니다. 이를 지정하지 않았지만 cut
표시된 명령을 사용하면 파일이 탭으로 구분되어 있음을 의미합니다. 그렇다면 uniq -c
출력이 공백(표시하지 않음)으로 줄을 채우고 발생 후에 탭을 추가하지 않는다는 점을 고려하면 다음과 같이 간단하게 작업을 수행할 수 있습니다.
$ sort file.csv | uniq -c | sort -nr | perl -pe 's/^\s+(\d+) (.*)/$2\t$1/'
2022-12-01 YELLOW 2 3
2022-12-01 RED 2 3
2022-12-01 YELLOW 1 2
2022-12-01 RED 1 2
또는 다음 sed
을 지원합니다 -E
.
$ sort file.csv | uniq -c | sort -nr | sed -E 's/^ *([0-9]*) (.*)/\2\t\1/'
2022-12-01 YELLOW 2 3
2022-12-01 RED 2 3
2022-12-01 YELLOW 1 2
2022-12-01 RED 1 2
그리고 어떤 sed에서도:
$ sort file.csv | uniq -c | sort -nr | sed 's/^ *\([0-9]*\) \(.*\)/\2\t\1/'
2022-12-01 YELLOW 2 3
2022-12-01 RED 2 3
2022-12-01 YELLOW 1 2
2022-12-01 RED 1 2
또는 개수를 계산하고 awk
원하는 위치에 필드를 추가한 후 네 번째 필드를 기준으로 정렬할 수 있습니다.
$ awk -F'\t' -v OFS='\t' '{ cnt[$0]++ }
END{
for(line in cnt){
print line,cnt[line]
}
}' file.csv | sort -nrk4,4
2022-12-01 YELLOW 2 3
2022-12-01 RED 2 3
2022-12-01 YELLOW 1 2
2022-12-01 RED 1 2
답변2
사용행복하다(이전 Perl_6)
당신이 원하는 것은 Bag
요소입니다. 이 경우 요소는 다음과 같습니다 lines
:
~$ raku -e '.say for lines.Bag;' file
입력 예(탭으로 구분):
2022-12-01 RED 1
2022-12-01 RED 1
2022-12-01 RED 2
2022-12-01 RED 2
2022-12-01 RED 2
2022-12-01 YELLOW 1
2022-12-01 YELLOW 1
2022-12-01 YELLOW 2
2022-12-01 YELLOW 2
2022-12-01 YELLOW 2
예제 출력:
2022-12-01 RED 2 3
2022-12-01 RED 1 2
2022-12-01 YELLOW 2 3
2022-12-01 YELLOW 1 2
참고: 여기서 실제 문제는 후행 공백일 수 있습니다. trim-trailing
각 줄의 오른쪽 끝에 공백을 제거하는 호출을 추가할 수 있습니다 .
~$ raku -e '.put for lines.map(*.trim-trailing).Bag;'
#OR
~$ raku -e '.put for lines>>.trim-trailing.Bag;'
답변3
count-distinct
Miller( ) 하위 명령을 사용하여 mlr
입력이 탭으로 구분되고 열 머리글이 없다고 가정하고 처음 세 필드에 고유 값이 있는 레코드 수를 계산합니다.
$ mlr --tsv -N count-distinct -f 1,2,3 file
2022-12-01 RED 1 2
2022-12-01 RED 2 3
2022-12-01 YELLOW 1 2
2022-12-01 YELLOW 2 3
개수는 필드 목록 끝에 새 필드로 추가됩니다. 입력을 정렬할 필요가 없습니다.
개수를 첫 번째 필드로 사용하려면 reorder
하위 명령을 사용하십시오. 제목이 출력에 표시되지 않더라도 작업 count
으로 생성된 명명된 필드를 참조 할 수 있습니다.count-distinct
$ mlr --tsv -N count-distinct -f 1,2,3 then reorder -f count file
2 2022-12-01 RED 1
3 2022-12-01 RED 2
2 2022-12-01 YELLOW 1
3 2022-12-01 YELLOW 2
답변4
awk 명령의 연관 배열 아이디어를 사용하면 고유한 행 수를 쉽게 계산할 수 있습니다.
$ awk '{a[$0]++} END {for (i in a) print a[i]"--->",i}' infile
2---> 2022-12-01 YELLOW 2
3---> 2022-12-01 RED 2
2---> 2022-12-01 YELLOW 1
1---> 2022-12-01 YELLOW 2
2---> 2022-12-01 RED 1