awk question para processar linhas com zeros em colunas

2

Oi eu tenho um arquivo com o seguinte formato:

nome do arquivo é foo.txt

abcd 1 0 0 2
abef 2 0 0 0
able 2 1 2 0
able 1 0 0 0
efgh 0 0 0 0

Eu escrevi um script awk para excluir a linha com todas as colunas com 0. Mas estou recebendo um erro de sintaxe. Tenho certeza que isso é muito simples.

Por favor, a qualquer momento pode me ajudar a corrigir isso?

awk 'BEGIN{i=1; While($2==0)($3==0)($4==0) {print $0} }' foo.txt
    
por genetwister 14.09.2017 / 21:47

4 respostas

3

tente

awk '$2 != 0 || $3 !=0 || $4 !=0 || $5 !=0 ' foo.txt

onde

  • isso filtrará a linha (grap) com pelo menos um zero diferente.
  • por favor, não awk receberá linha, um por um, não há necessidade por enquanto.
  • também o arquivo original não será editado.

Editar:

"exatamente o oposto" é um pouco confuso, no entanto, para obter linha com

  • todo o último campo sendo 0 use $2 == 0 && $3 == 0 && ... ( && significa lógico e awk, || é lógico ou)
  • pelo menos 0 use $2==0 || $3==0 || ...

se você tiver muitos campos, para ter linha com zero:

awk 'NF>2 {for(i=2;i<=NF;i++) if ($i) {print ; next ;}}' file

onde

  • NF é o número de campos
  • NF>2 assegura que a linha tenha pelo menos 2 campos e que o loop termine.
por 14.09.2017 / 21:56
2

Solução GNU awk (para filtrar registros com zeros):

awk -v FPAT='[1-9][0-9]*' 'NF' foo.txt
Bônus sed abordagem alternativa:

sed -E '/^[^[:space:]]+ (0[[:space:]]*){4,}$/d' foo.txt

A saída (para ambas as abordagens):

abcd 1 0 0 2
abef 2 0 0 0
able 2 1 2 0
able 1 0 0 0
    
por 14.09.2017 / 22:43
0
$ awk '{ c = 0 } { for (i = 2; i <= NF && c == 0; ++i) { c += ($i != 0) } } c > 0' foo.txt
abcd 1 0 0 2
abef 2 0 0 0
able 2 1 2 0
able 1 0 0 0

O script percorre todos os campos (pulando o primeiro) e conta quantos não-zeros existem (na verdade, a contagem pára assim que encontra um valor diferente de zero, mas isso é apenas uma pequena otimização). Se houver algum não-zeros, o registro de entrada é impresso.

NF é o número de campos (colunas) no registro de entrada (linha) e $i faz referência ao campo i . A ação padrão para c > 0 , que não possui um bloco { ... } , é imprimir o registro de entrada.

Uma maneira equivalente de escrever este script seria

awk '{ c = 0; for (i = 2; i <= NF && c == 0; ++i) { c += ($i != 0) } } c > 0 { print }'

Seu código tem os seguintes problemas:

  1. Uma instrução while parece com while (expression) { code } , enquanto você tem while (expression) (expression) ... { code } . Este é um erro de sintaxe.
  2. O bloco BEGIN é executado antes que os primeiros dados sejam lidos do arquivo, portanto, $0 , $1 etc. não teria nenhum valor dentro dele.
por 14.09.2017 / 22:09
0

Faça simplesmente:

awk '$2+$3+$4+$5' infile

Ou até mesmo este, se a primeira coluna for sempre alfabética:

awk '$0 ~ /[1-9]/' infile
    
por 14.09.2017 / 22:18

Tags