Eu tenho um arquivo como este que é separado por tabulação:
name v1 v2 v3 v4
g1 4.5 2.3 2.1 0.2
g2 10 3 5 2.3
g3 7 2.5 2.8 3.9
Apenas mostrando acima de um arquivo fictício onde tenho 5 colunas e 4 linhas (incluindo o cabeçalho). Eu quero filtrar as linhas de tal forma que, se cada coluna em uma linha específica tiver valor >= 2, mantenha essa linha, caso contrário, remova-a. A saída deve ficar assim:
name v1 v2 v3 v4
g2 10 3 5 2.3
g3 7 2.5 2.8 3.9
Como posso fazer isso usando o awk?
O AFAIK awk não tem como fazer isso a não ser iterar sobre os campos explicitamente. Por exemplo:
A steeldriver já forneceu uma solução awk. Aqui está uma versão perl (usando uma fatia de matriz em vez de um loop for):
Isso imprime apenas a primeira linha (cabeçalho) e as linhas em que todos os campos numéricos têm um valor maior ou igual a 2. (campos não numéricos como
g1
oug2
serão avaliados como0
)Nota: a
grep()
função do perl é similar em conceito, mas não exatamente igual aogrep
programa de linha de comando.grep(expression,array)
executa a expressão em seu primeiro argumento (por exemplo ,$_ >= 2
) em todos os elementos de um array (por exemplo@F
, ), e retorna um array que consiste em todos os elementos em que o resultado foi verdadeiro.Em um contexto escalar (como uma comparação numérica com um inteiro), ele retorna o número de vezes que a expressão foi verdadeira, em vez de uma matriz. Isso é o que estamos fazendo aqui com
== $#F
, para testar a equivalência com$#F
(o número de elementos em array@F
)A expressão pode ser um teste simples, conforme usado neste exemplo, ou um bloco de código contendo qualquer código perl. Ele também pode modificar opcionalmente cada elemento. por exemplo
@new = grep(s/foo/bar/g, @old)
, preencheria @new com todos os elementos de @old que foram modificados com sucesso (ou seja, thost que continha pelo menos um "foo". Todos os quais foram alterados para "bar"). Vejaperldoc -f grep
para detalhes.