bash에서 열의 고유 값 수 가져오기
여러 열로 구분된 탭 파일이 있습니다.폴더에 있는 모든 파일에 대해 열에서 서로 다른 값이 발생하는 빈도를 세고 카운트가 감소하는 순서(가장 높은 카운트 우선)로 정렬하려고 합니다.Linux 명령줄 환경에서 이 작업을 수행하려면 어떻게 해야 합니까?
awk, perl, python 등의 공통 명령행 언어를 사용할 수 있습니다.
2열에 대한 주파수 카운트를 보려면(예:
awk -F '\t' '{print $2}' * | sort | uniq -c | sort -nr
파일 A.txt
z z a
a b c
w d e
파일 B.txt
t r e
z d a
a g c
파일 C.txt
z r a
v d c
a m c
결과:
3 d
2 r
1 z
1 m
1 g
1 b
셸에서 수행할 수 있는 방법은 다음과 같습니다.
FIELD=2
cut -f $FIELD * | sort| uniq -c |sort -nr
이것이 바로 bash가 잘하는 종류의 것입니다.
GNU 사이트는 단어와 빈도를 모두 인쇄하는 이 멋진 어색한 스크립트를 제안합니다.
변경 가능성:
- 파이프로 통과할 수 있습니다.
sort -nr(및 그 반대)word그리고.freq[word])을 클릭하여 내림차순으로 결과를 확인합니다. - 특정 열이 필요하면 for 루프를 생략하고 간단히 다음과 같이 쓸 수 있습니다.
freq[3]++3을 열 번호로 바꿉니다.
다음과 같습니다.
# wordfreq.awk --- print list of word frequencies
{
$0 = tolower($0) # remove case distinctions
# remove punctuation
gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
for (i = 1; i <= NF; i++)
freq[$i]++
}
END {
for (word in freq)
printf "%s\t%d\n", word, freq[word]
}
펄
이 코드는 모든 열의 발생을 계산하고 각 열의 발생에 대해 정렬된 보고서를 인쇄합니다.
# columnvalues.pl
while (<>) {
@Fields = split /\s+/;
for $i ( 0 .. $#Fields ) {
$result[$i]{$Fields[$i]}++
};
}
for $j ( 0 .. $#result ) {
print "column $j:\n";
@values = keys %{$result[$j]};
@sorted = sort { $result[$j]{$b} <=> $result[$j]{$a} || $a cmp $b } @values;
for $k ( @sorted ) {
print " $k $result[$j]{$k}\n"
}
}
텍스트를 열 값으로 저장합니다.플
실행 방법:perl columnvalues.pl files*
설명.
루프 중 최상위 수준에서:
결합된 입력 파일의 각 행에 대한 루프
줄을 @Fields 배열로 분할
각 열에 대해 결과 해시 배열 데이터 구조를 증가시킵니다.
루프에 대한 최상위 수준:
결과 배열을 반복합니다.
열 번호 인쇄
해당 열에 사용된 값을 가져옵니다.
발생 횟수에 따라 값 정렬
값을 기준으로 한 보조 정렬(예: b vs g vs m vs z)
정렬된 목록을 사용하여 결과 해시를 반복합니다.
각 발생의 값과 수를 인쇄합니다.
@Dennis에서 제공한 샘플 입력 파일을 기반으로 한 결과
column 0:
a 3
z 3
t 1
v 1
w 1
column 1:
d 3
r 2
b 1
g 1
m 1
z 1
column 2:
c 4
a 3
e 2
.csv 입력
입력 파일이 .csv인 경우 변경/\s+/로./,/
난독화
보기 흉한 대회에서 펄은 특히 장비가 잘 갖춰져 있습니다.
이 단일 라이너는 다음과 같습니다.
perl -lane 'for $i (0..$#F){$g[$i]{$F[$i]}++};END{for $j (0..$#g){print "$j:";for $k (sort{$g[$j]{$b}<=>$g[$j]{$a}||$a cmp $b} keys %{$g[$j]}){print " $k $g[$j]{$k}"}}}' files*
루비(1.9+)
#!/usr/bin/env ruby
Dir["*"].each do |file|
h=Hash.new(0)
open(file).each do |row|
row.chomp.split("\t").each do |w|
h[ w ] += 1
end
end
h.sort{|a,b| b[1]<=>a[1] }.each{|x,y| print "#{x}:#{y}\n" }
end
여기를 피함으로써 선형 시간에 접근하는 까다로운 것이 있습니다(그러나 아마도 더 빠르지는 않을 것입니다!).sort그리고.uniq최종 분류를 제외하고는.그것은 ...에 기초를 두고 있습니다. tee그리고.wc대신에!
$ FIELD=2
$ values="$(cut -f $FIELD *)"
$ mkdir /tmp/counts
$ cd /tmp/counts
$ echo | tee -a $values
$ wc -l * | sort -nr
9 total
3 d
2 r
1 z
1 m
1 g
1 b
$
Pure-Bash 버전:
FIELD=1
declare -A results
while read -a line; do
results[${line[$FIELD]:-(empty)}]=$((results[${line[$FIELD]:-(empty)}]+1));
done < file.txt
echo ${results[@]@A}
키 로직은 연관 배열을 채우는 것입니다. 연관 배열의 키는 파일에 있는 값이고 배열의 값은 발생 횟수입니다.
$FIELD한 열 입니다.${line[$FIELD]}열 입니다.${...:-(empty)}빈 값에 대한 특수한 경우입니다(예상보다 적은 열이 있는 경우 어떻게 됩니까?).
출력을 예상 OP 형식으로 정렬하려면 다음 작업이 조금 더 필요합니다.
sort -rn < <(
for k in "${!results[@]}"; do
echo "${results[$k]} $k";
done
)
경고: 탭 구분 및 공백 구분 파일에는 잘 작동하지만 공백이 있는 값에는 잘 작동하지 않습니다.
언급URL : https://stackoverflow.com/questions/4921879/getting-the-count-of-unique-values-in-a-column-in-bash
'programing' 카테고리의 다른 글
| 완성도를 사용하지 않는 홈브루의 기트 (0) | 2023.07.04 |
|---|---|
| 공유 호스팅 환경에서 MongoDB를 설정할 수 있습니까? (0) | 2023.06.29 |
| Microsoft를 사용하여 숫자, 텍스트 및 날짜와 같은 데이터 유형을 Excel 열에 설정합니다.사무실. 인터럽트.c#에서 탁월함 (0) | 2023.06.29 |
| asp.net 바이올린이 있습니까? (0) | 2023.06.29 |
| 해시 충돌 git (0) | 2023.06.29 |