supprimer les lignes où la valeur d'un champ est inférieure ou égale à 3 - sed ou awk?

17

Je dois supprimer chaque ligne qui a une valeur de 2 ou moins dans le 8ème champ (colonne).

Mes données ressemblent à ceci:

12-31   Airport 189 379 41  49.70946503 -124.91377258   2   2880    30.8
01-01   AlberniElementary   165 331 16  49.26100922 -124.80662537   4   5760    26.1
01-09   BamfieldMarine  161 323 23  48.83490372 -125.13572693   2   2875    27.4
01-10   BamfieldMarine  161 323 23  48.83490372 -125.13572693   3   3068    38.6

Je comprends qu'en utilisant awk, je peux supprimer les valeurs souhaitées et les imprimer dans un autre fichier, et je comprends que sed modifierait le fichier actuel. Dans les deux cas, je dois conserver le fichier d'origine.

Remarque : veuillez fournir des explications détaillées avec vos solutions. Il ne suffit pas d'écrire simplement la commande, veuillez annoter les suggestions.

Remarque supplémentaire : les données ont une ligne d'en-tête, donc la solution la plus probable devra

awk 'FNR> 1'

Je suppose?

geokrowding
la source

Réponses:

19

Vous l'avez presque compris.

 awk '(NR>1) && ($8 > 2 ) ' foo > bar

  • NR est le nombre d'enregistrements (c'est-à-dire le nombre de lignes)
  • $8 est huit champs
  • && est logique et
  • foo est le fichier d'origine, inchangé
  • bar fichier résultant
  • l'action implicite par défaut consiste à imprimer la ligne d'entrée actuelle

Notez que l'en-tête est rayé de foo à bar, pour le garder

 awk '(NR==1) || ($8 > 2 ) ' foo > bar

  • || est logique ou
  • la ligne d'entrée est imprimée si NR == 1 ou si 8 $> 2

Mise à jour # 1

Pour spécifier une plage

  • ( ($8 >= -4) && ( $8 <= 4 ) ) 8ème champ de -4 à 4
  • (NR == 1 ) || ( ($8 >= -4) && ( $8 <= 4 ) ) même, y compris en-tête
Archemar
la source
Grande réponse: simple mais approfondie, merci. Juste pour être clair, la différence entre FNR et NR dans ce cas n'est rien, n'est-ce pas? J'ai lu l' homme page où il explique: le numéro NR de l'enregistrement en cours et FNR nombre ordinal de l'enregistrement en cours dans le fichier actuel. Je comprends donc que ces éléments sont égaux dans ce cas, je pense :)
geokrowding
Si vous avez un fichier, FNR est toujours NR, si le fichier1 a 10 lignes, la première ligne du fichier2 aurait NR = 11 et FNR = 1
Archemar
Salut, je veux faire quelque chose de similaire mais accepter tout dans une plage de -4 à 4. comment pourrais-je faire cela, car c'est la seule façon dont je peux penser à le faire actuellement awk '(NR == 1) || (8 $ = [-4-4]) 'foo> bar
Giles
1
awk ne connaît pas la plage de style mathématique, voir ma modification.
Archemar