web-dev-qa-db-fra.com

Suppression de lignes en fonction des valeurs de colonne d'un fichier à l'aide de la commande awk

J'ai un fichier énorme comme ci-dessous. Je veux supprimer les lignes si la deuxième colonne a les valeurs 60,30, etc., toutes ces valeurs que je vais obtenir à partir d'un autre fichier dans un fichier séparé par des virgules.

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

Je peux utiliser la commande awk ci-dessous pour y parvenir, mais si j'ai plusieurs valeurs à exclure, existe-t-il un moyen simple de le faire?.

$ 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
3
prasanth doni

Mettez vos valeurs dans un autre fichier:

values:

60
25
30

Puis lisez-les dans un tableau dans awk:

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

FNR == NR est vrai lors de la lecture du premier fichier, le premier bloc n'est donc exécuté que lors de la lecture des valeurs. En raison de next, la !($2 in arr) n'est exécutée que pour le deuxième fichier.

4
muru

Votre commande peut être simplifiée davantage - vous n'avez pas besoin de l'instruction if et du bloc de code, car awk peut imprimer des lignes en utilisant la condition correspondante qui précède le bloc de code. Si vous souhaitez uniquement imprimer la ligne, vous pouvez ignorer le bloc de code:

$ 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

Une autre solution serait d'utiliser le tableau:

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

Ce qui se passe là-bas, c'est que nous créons une chaîne avec toutes les valeurs que nous voulons, séparées par un espace. Dans l'instruction BEGIN, nous le décomposons en tableau. Les blocs de code principaux définissent la variable flag sur 0 lors de la lecture de chaque ligne, puis nous parcourons toutes les valeurs du tableau et vérifions si le champ n ° 2 correspond à quoi que ce soit dans le tableau. Si tel est le cas, nous définissons l'indicateur sur 1. Une fois la boucle terminée, nous voyons si la boucle a trouvé quelque chose et définissons l'indicateur. Sinon, affiche la ligne.

La version la plus courte de cette approche consiste à utiliser la commande next pour rompre la boucle si la valeur exclue est trouvée. De cette façon, la fonction print est atteinte uniquement si aucune valeur exclue n'a été trouvée:

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