Imprimir Coluna se os valores estiverem entre dois outros valores

2

Sou relativamente novo na análise de dados e tenho um problema com a filtragem de alguns dos meus valores. Eu tenho dados organizados em um arquivo com quatro colunas como esta:

A   1       10     5
B   10      100    120
C   100     1000   1200 
D   1000    10000
E   10000   100000
F   100000  1000000
G   1000000 10000000

O que eu quero fazer agora é imprimir apenas as linhas onde os valores na coluna 4 estão entre os valores nas colunas 2 e 3. Então, algo assim:

A 1 10 
C 100 1000
D 1000 10000

Eu tentei com grep e awk, por exemplo %código%. Embora o problema seja que o awk pesquisa apenas dentro da mesma linha e não para todas as linhas onde ele corresponde a esse critério. Eu acho que é bastante simples, mas não consegui descobrir como fazer isso.

    
por Thomas 10.02.2014 / 15:47

3 respostas

3

Isso fará o que eu pensar que você está pedindo. Ele coleta todos os valores da quarta coluna e, em seguida, para todas as linhas no arquivo e todos os valores vistos na quarta coluna, a linha será impressa se qualquer um dos 4º valores estiver entre os valores na linha.

perl -lane '$want{$F[$#F]}++; foreach $wanted (keys(%want)){
               if($wanted > $F[1] && $wanted < $F[2]){print "@F[0..2]"} 
             }' file
A 1 10
C 100 1000
D 1000 10000

No entanto, como você pode ver acima, isso não produz a saída mostrada. Está imprimindo linha C porque 100 < 120 < 1000 e não está imprimindo linha E porque nenhum dos valores da 4ª coluna está entre 10000 e 100000.

Explicação

A opção -a para perl faz com que ela divida automaticamente o arquivo de entrada em campos no espaço em branco e salve os campos como a matriz @F . Então, eu salvei o último campo ( $F[$#F] ) no hash %wanted , e para cada linha, eu passei pelas chaves do hash que tenho até agora e imprimo os campos do primeiro ao terceiro ( @F[0..2] ) do hash linha se algum deles estiver entre os valores.

Note que isto não funcionará se o seu arquivo não estiver ordenado, se um dos números da 4a coluna puder aparecer após uma linha que satisfaria. Se isso pode acontecer, você precisa ler o arquivo duas vezes, algo assim:

 perl -le 'open(A,"$ARGV[0]"); while(<A>){@F=split(/\s+/); $want{$F[$#F]}++}; 
           open(A,"$ARGV[0]"); while(<A>){@F=split(/\s+/);
            foreach $wanted (keys(%want)){
                if($wanted > $F[1] && $wanted < $F[2]){print "@F[0..2]"}
            }} ' file

Você também pode usar a resposta do @Stathane, que também lê o arquivo duas vezes.

    
por 10.02.2014 / 16:57
3
awk 'NR == FNR {if (NF >= 4) a[$4]; next}
     {for (i in a) if (+i >= $2 && +i <=$3) {print $1, $2, $3; next}}' file file
    
por 10.02.2014 / 17:04
1

algo assim?

awk '$4 <= $3 && $4 >= $2' data
A 1 10 5

sem a quarta coluna:

awk '($4 <= $3 && $4 >= $2){print $1,$2,$3}' data
A   1   10
    
por 10.02.2014 / 16:06