AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 543899
Accepted
Age87
Age87
Asked: 2019-09-27 08:16:56 +0800 CST2019-09-27 08:16:56 +0800 CST 2019-09-27 08:16:56 +0800 CST

Contar o número de TRUEs em um campo, relatando o número do campo, o número de TRUEs e a contagem de rótulos (grandes ou pequenos)

  • 772

Tenho um código rodando em uma máquina Linux, que conta o número de TRUEs encontrados em uma determinada coluna/campo, imprimindo como saída o número da coluna e o número de TRUEs naquela coluna.

Na nova entrada, as linhas são atribuídas (última coluna na entrada) como "grande" ou "pequena" (três de cada).

Eu gostaria de contar o número de "pequenos" e "grandes" para cada coluna com 2 ou mais TRUEs.

Código para encontrar colunas com 2 ou mais TRUEs (sei que o código abaixo ignora a primeira coluna de entrada):

awk -vtc=2 'NR==1{next};
                NR==2{for(i=2;i<=NF;i++){t[i]=0}};
                {for(i=2;i<=NF;i++){if($i=="TRUE"){t[i]++}}}
                END{
                    for(j in t)
                    if(t[j]>=tc){print(j,t[j])}
                }' input.tsv > output.tsv

Entrada.tsv:

MT MT MT MT MT MT MT MT MT MT
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE

output.tsv:

(primeira coluna: número da coluna; segunda coluna: número de TRUEs)

3 3
6 3
9 2
10 2

nova entrada.tsv

MT MT MT MT MT MT MT MT MT MT CAT
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE LARGE        
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE SMALL         
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE SMALL        
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE SMALL        
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE LARGE     
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE LARGE

Saída desejada.tsv:

(terceira coluna: número de TRUEs atribuídos como pequenos; quarta coluna: número de TRUEs atribuídos como grandes)

3 3 2 1
6 3 1 2
9 2 1 1
10 2 0 2

A ajuda de qualquer um de vocês linux wizards é muito apreciada!

text-processing
  • 3 3 respostas
  • 202 Views

3 respostas

  • Voted
  1. Best Answer
    iruvar
    2019-09-27T15:04:29+08:002019-09-27T15:04:29+08:00

    Uma solução que usa (pseudo) arrays multidimensionais emawk

    awk '
    BEGIN {
        b["TRUE"] = 1
        b["FALSE"] = 0
    }
    FNR > 1 {
        for (i=1; i < NF; ++i)
            a[i, $NF] += b[$i]
    }
    END {
        s = "SMALL"
        l = "LARGE"
        for (j=1; j<=i; ++j)
            if (a[j, s] || a[j, l])
                print j, a[j, s] + a[j, l],
                a[j, s] + 0,
                a[j, l] + 0
    }' input.tsv
    

    Ou usando verdadeiros arrays multidimensionais disponíveis no GNU awk

    awk '
    FNR > 1 {
        for (i=1; i < NF; ++i)
            if ($i == t)
                ++a[i][$NF] 
    }
    END {
        for (j in a)
            print j, a[j][s] + a[j][l],
            +a[j][s],
            +a[j][l]
    }' t=TRUE s=SMALL l=LARGE input.tsv
    
    • 3
  2. bu5hman
    2019-09-27T10:48:30+08:002019-09-27T10:48:30+08:00

    Marreta deselegante, mas parece funcionar

    #!/bin/bash
    
    cols=$(echo $(head -n 1 file) | awk '{print gsub(/ /, "")}')
    sed -e "1d" -e "s/TRUE/1/g" -e "s/FALSE/0/g" -e "s/ /,/g" file > tmp1
    sed "/,S.*/d" tmp1 > tmp2
    for s in $(seq 1 $cols); do
        tr=$(cut -d, -f$s tmp1 | paste -s -d+ | bc --)
        if [ $tr -gt 0 ]; then
            trl=$(cut -d, -f$s tmp2 | paste -s -d+ | bc --)
            echo $s $tr $(( $tr-$trl )) $trl
        fi
    done | column -t -N Col,True,Small,Large
    rm tmp1 tmp2
    

    Resultado

    Col  True  Small  Large
    3    3     2      1
    6    3     1      2
    9    2     1      1
    10   2     0      2
    

    EDITAR

    Um pouco menos ofensivo emawk

    #!/bin/bash
    
    sed -e "1d" -e "s/TRUE/1/g" -e "s/FALSE/0/g" file | awk '{
        for (i=1; i<NF; i++)
            {sumall[i]+= $i; if ($NF == "LARGE") {sumlarge[i]+= $i}};
        } END {
        for (x in sumall)
            if (sumall[x] > 0)
                { print x, sumall[x], sumall[x]-sumlarge[x], sumlarge[x]}
        }' | column -t -N Col,True,Small,Large
    
    • 1
  3. Rakesh Sharma
    2019-09-28T00:50:11+08:002019-09-28T00:50:11+08:00

    Isso usa pipelines com diferentes utilitários sendo invocados:

    $ sed -E '1d;s/FALSE/0/g;/LARGE$/s/TRUE/L/g;s/TRUE/S/g' input.tsv |
      datamash transpose |
      perl -F'\t' -lane '$,="\t"; my %h;
        my $c = grep { /^([LS])$/ && ++$h{$1} } @F;
        print $., $c, $h{S}||0, $h{L}||0 if $c > 1;
      '
    3   3   2   1
    6   3   1   2
    9   2   1   1
    10  2   0   2
    
    • 0

relate perguntas

  • Grep para um conjunto de linhas de $START a $END AND que contém uma correspondência em $MIDDLE

  • Reorganize as letras e compare duas palavras

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Embaralhamento de arquivo de várias linhas

  • como posso alterar o caso do caractere (de baixo para cima e vice-versa)? ao mesmo tempo [duplicado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve