Contar colunas que possuem 0 e 1

0

Eu tenho uma tabela que contém 0, 1 e -9.

-9  -9  0   1   1
-9  1   0   0   0
0   -9  0   1   -9
-9  -9  1   0   -9
-9  -9  0   0   0

Eu quero saber quantas colunas têm 0 e 1. No exemplo, a resposta é 3.

Eu estava pensando em combinar awk e print para imprimir "true" caso a coluna contenha ambos 0 e 1 (e imprima false caso contrário).

Eu teria então | grep true | wc -l para contar o número da coluna.

Parece uma boa solução? Ou como posso fazer isso com awk ?

    
por user283771 01.04.2018 / 14:20

6 respostas

0
awk '
{
    for (i=1;i<=NF;++i)
        if      ($i == 1) ++one[i]
        else if ($i == 0) ++zero[i]
}
END { 
    for (i=1;i<=NF;++i)
        c += (one[i]>0 && zero[i]>0)
    print c
}' file

Isso conta os zeros e uns em dois arrays separados, one e zero . Estes têm uma entrada por coluna no arquivo de entrada.

No final, a variável c será a soma do número de colunas que tem pelo menos um 1 e um 0 . O código assume que o número de colunas na última linha de entrada é o mesmo que nas outras linhas dos dados de entrada.

A saída disso com os dados de exemplo fornecidos é 3 .

    
por 01.04.2018 / 16:26
2

tente com (isso feio)

awk '{if ( NF>maxi) maxi =NF ; 
       for(i=1;i<=NF;i++) {if ( $i == 0 ) zero[i]=1 ; 
               if ($i ==1 ) one[i]=1 ;}}
     END { for (i=1;i<=maxi;i++) if ( zero[i]+one[i]==2) print i ;}' file

isso basicamente configura um sinalizador para 0 e 1 para cada coluna. soma de ambos deve ser 2.

    
por 01.04.2018 / 15:47
2

ruby é legal para trabalhar com matrizes de matrizes:

ruby -e '
    rows = File.readlines( ARGV.shift ).map {|line| line.split}
    columns = rows.transpose
    puts columns.count {|column| column.include?("0") and column.include?("1")}
' file

ou, sem variáveis

ruby -e 'puts readlines
                .map {|line| line.split}
                .transpose
                .count {|column| column.include?("0") and column.include?("1")}
' file
    
por 01.04.2018 / 15:25
1

com BSD rs :

<file rs -T | grep -w 0 | grep -wc 1

Onde:

  • rs -T transpõe a matriz
  • grep -w 0 seleciona as linhas (anteriormente colunas) que contêm 0 como um único w ord
  • grep -wc 1 conta o número de linhas restantes (inicialmente colunas) que contêm 1 como uma única palavra

No entanto, palavras para grep -w são sequências de alnums ou sublinhados, por isso, embora 1 não seja encontrado em 10 , seria encontrado se -1 as - não é nem alnum nem sublinhado.

Se -1 pode ocorrer na entrada, você pode querer alterá-la para:

<file rs -T | sed 's/.*/ & /' | grep ' 0 ' | grep -c ' 1 '
    
por 01.04.2018 / 21:15
0

Awk solução:

awk '{ for (i=1; i<=NF; i++) a[i] = (NR > 1? a[i] : "") $i; }
     END{ 
         for (i in a) if (a[i] ~ /(0.*1|1.*0)/) c++;
         print c 
     }' file

A saída:

3
    
por 01.04.2018 / 15:56
0

Com datamash + awk supondo que seus campos estão separados por um único espaço:

$ datamash -t' ' transpose <infile | awk '/0/ && /1/{++C} END{print C}'
3
    
por 01.04.2018 / 17:30