web-dev-qa-db-fra.com

Utilisation de AWK pour filtrer les colonnes avec des plages numériques

Je suis relativement nouveau chez BASH et j'essaie d'utiliser awk pour filtrer les données de la colonne 1 en fonction de la 4ème colonne d'un fichier texte. Si la 4ème colonne de données correspond à la plage de x, elle produira les données de la colonne 1. "x" est supposé être une plage de nombres 1-10 (1,2,3..10). 

awk -F: '{ if($4=="x") print $1}' filename.txt

filename.txt 
sample1 0 0 4
sample2 0 0 10
sample3 0 0 15
sample4 0 0 20

Utilisation réelle:

awk -F: '{ if($4=="1-10") print $1}' sample.txt
output = sample1, sample2, sample3, sample4

Il devrait être: sample1 sample2 seulement.

Y at-il une erreur dans la syntaxe que je ne vois pas ou je pourrais éventuellement utiliser cette syntaxe complètement fausse?

31
BurN135
awk '{ if ($4 >= 1 && $4 <= 10) print $1 }' sample.txt
62
Kambus
awk '$4 ~ /^[1-9]$|^10$/{print $1}' sample.txt

sortie:

sample1
sample2

explication:

  • ^[1-9]$ -> 4 $ doit être un seul chiffre compris entre 1 et 9
  • | (le tuyau) -> ou
  • ^10$ -> 4 $ doit être le nombre 10
13
olibre
awk -F ':' '$4 >= 1 && $4 <= 10{print $1}'
4
Gregory Patmore

Il peut y avoir un moyen de le faire en utilisant seulement awk (tant pis, voyez mon édition ci-dessous), mais je ne le sais pas. Je le combinerais avec grep: 

egrep ' ([1-9]|10)$' sample.txt | awk '{print $1}'

Je pense que vous faites correspondre la quatrième colonne avec la chaîne "1-10" pas la plage. De plus, -F: changera le délimiteur en deux points plutôt qu'en un espace. 

Modifier: 

awk '$4 ~ /^([1-9]|10)$/ {print $1}' sample.txt
2
gpojd

Si Perl est une option, vous pouvez essayer cette solution similaire à la solution awk de Kambus:

Perl -lane 'print $F[0] if $F[3] >= 1 && $F[3] <= 10' sample.txt

Ces options de ligne de commande sont utilisées:

  • -n boucle autour de chaque ligne du fichier d'entrée, ne pas imprimer automatiquement chaque ligne

  • -l supprime les nouvelles lignes avant traitement et les rajoute après

  • -a mode autosplit - divise les lignes d’entrée dans le tableau @F.

  • -e exécuter le code Perl

@F est le tableau de mots de chaque ligne, indexé à partir de 0

1
Chris Koknat

Si vous souhaitez que awk recherche les valeurs d'une plage, vous pouvez définir cette plage dans l'instruction BEGIN

awk 'BEGIN{for (i=1;i<=10;i++) a[i]} ($4 in a){print $1}' sample.txt 

Tester:

[jaypal:~/Temp] cat sample.txt 
sample1 0 0 4
sample2 0 0 10
sample3 0 0 15
sample4 0 0 20
[jaypal:~/Temp] awk 'BEGIN{for (i=1;i<=10;i++) a[i]} ($4 in a){print $1}' sample.txt 
sample1
sample2
1
jaypal singh