Excluindo linhas com base nos valores da coluna em um arquivo usando o comando awk

3

Eu tenho um arquivo enorme como abaixo. Eu quero excluir as linhas se a segunda coluna está tendo valores 60,30 etc, todos esses valores eu vou ter de outro arquivo em arquivo separado por vírgula.

position_id risk_measure_id Scenario_id value_usd
1   60  0   300.8
2   30  0   400.6
3   45  90  300.7
4   60  0   200.9
5   30  9   400.8
6   60  10  4000.9
8   20  0   5000.9

Eu posso usar o comando abaixo awk para alcançá-lo, mas se eu tiver vários valores para excluir, existe uma maneira fácil.

$ awk '{ if ($2!=60 && $2!=25 && $2!=30) print $0}' test.txt
position_id risk_measure_id Scenario_id value_usd
3   45  90  300.7
8   20  0   5000.9
    
por prasanth doni 12.01.2017 / 02:53

2 respostas

4

Coloque seus valores em outro arquivo:

values :

60
25
30

Depois, leia-os em uma matriz em awk :

awk 'FNR == NR {arr[$0] = 1; next} !($2 in arr)'  values test.txt

FNR == NR é válido ao ler o primeiro arquivo, portanto, o primeiro bloco é executado apenas durante a leitura dos valores. Por causa do next , o !($2 in arr) é executado apenas para o segundo arquivo.

    
por muru 12.01.2017 / 03:04
2

Seu comando pode ser simplificado ainda mais - você não precisa da instrução if e do bloco de código, porque o awk pode imprimir linhas usando uma condição de correspondência que precede o bloco de código. Se você quiser apenas imprimir a linha, o bloco de código pode ser ignorado:

$ awk '$2!=60 && $2!=25 && $2 != 30'  input.txt        
position_id risk_measure_id Scenario_id value_usd
3   45  90  300.7
8   20  0   5000.9

A solução alternativa seria usar array:

awk -v values="60 30 25" 'BEGIN{split(values,array)};{ flag=0; for(val in array) if (array[val] == $2) flag=1; if (flag==0) print }'  input.txt

O que acontece é que criamos uma string com todos os valores que queremos, separados por espaço. Na instrução BEGIN, dividimos em array. O bloco de código principal define a variável de sinalizador como 0 ao ler cada linha, então percorremos todos os valores da matriz e verificamos se o campo nº 2 corresponde a qualquer coisa na matriz. Em caso afirmativo, definimos o sinalizador como 1. Depois que o loop é encerrado, vemos se o loop encontrou alguma coisa e definiu a sinalização, e se isso não ocorreu, imprima a linha.

A versão mais curta dessa abordagem é usar o comando next para interromper o loop se o valor excluído for encontrado. Dessa forma, print function é atingida apenas se não houver nenhum valor excluído:

awk -v values="60 30 25" 'BEGIN{split(values,array)};{for(val in array) if (array[val] == $2) next; print}'  input.txt 
    
por Sergiy Kolodyazhnyy 12.01.2017 / 04:50