programing

Bash의 열에서 고유 값 수 가져 오기

nasanasas 2020. 9. 11. 08:07
반응형

Bash의 열에서 고유 값 수 가져 오기


여러 열이있는 탭으로 구분 된 파일이 있습니다. 폴더의 모든 파일에 대해 열에있는 다른 값의 발생 빈도를 계산하고 내림차순으로 정렬합니다 (가장 높은 개수부터). Linux 명령 줄 환경에서이 작업을 어떻게 수행합니까?

awk, perl, python 등과 같은 일반적인 명령 줄 언어를 사용할 수 있습니다.


2 열의 빈도 수를 보려면 (예 :)

awk -F '\t' '{print $2}' * | sort | uniq -c | sort -nr

fileA.txt

z    z    a
a    b    c
w    d    e

fileB.txt

t    r    e
z    d    a
a    g    c

fileC.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 사이트는 단어와 자신의 주파수를 모두 출력이 좋은 awk 스크립트를 제안합니다.

가능한 변경 :

  • 당신은을 통해 파이프를 수 sort -nr(및 역방향 wordfreq[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]
 }

Perl

이 코드는 모든 열의 발생을 계산하고 각 열에 대해 정렬 된 보고서를 인쇄합니다.

# 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"
    }
}

텍스트를 columnvalues.pl로 저장합니다. 다음으로
실행합니다.perl columnvalues.pl files*

설명

최상위 while 루프에서 :
* 결합 된 입력 파일의 각 행에 대해 루프
* 행을 @Fields 배열로 분할
* 모든 열에 대해 결과 배열 해시 데이터 구조 증가

In the top-level for loop:
* Loop over the result array
* Print the column number
* Get the values used in that column
* Sort the values by the number of occurrences
* Secondary sort based on the value (for example b vs g vs m vs z)
* Iterate through the result hash, using the sorted list
* Print the value and number of each occurrence

Results based on the sample input files provided by @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 input

If your input files are .csv, change /\s+/ to /,/

Obfuscation

In an ugly contest, Perl is particularly well equipped.
This one-liner does the same:

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*

Ruby(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

참고URL : https://stackoverflow.com/questions/4921879/getting-the-count-of-unique-values-in-a-column-in-bash

반응형