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.