Script shell pour valider les champs csv

J’ai un fichier csv avec 20 champs. Je veux avoir un script pour vérifier si le fichier est valide en fonction des points suivants:

  • Il doit avoir 20 champs séparés par des tuyaux.
  • Chacun des 20 champs doit correspondre à une expression régulière.
  • Connaître le numéro de ligne et de champ pour tout désaccord de regex.

ex:

f1|f2|f3|...|f20 1|aaaa|Y|...|2014/06/25 2|bb|Y...|2014/06/25 3|ccc|N...|2014/06/25 regex: f1 [0-9] f2 [az]{2,4} f3 [YN] . . . f20 [1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] 

Quels sont les meilleurs outils shell pour le faire? Avez-vous un script similaire?

Le meilleur outil dans les systèmes Unix est awk pour ce travail. Vous pouvez utiliser une commande awk comme ceci:

 awk 'BEGIN{FS=OFS="|"} NF!=20{print "not enough fields"; exit} !($1~/^[0-9]$/) {print "1st field invalid"; exit}' file.csv 

Vous pouvez envisager d’utiliser un script perl pour cela:

 #!/usr/bin/env perl use ssortingct; use warnings; my @regexes = ( qr/\d/, # regex quotes qr/ / qr/[az]{2,4}/, qr/[YN]/, #etc. put the rest of the regexes here ); while (<>) { # loop through every line of file my @fields = split /\|/; # split on pipe, needs escaping if (@fields != 20) { print "incorrect number of fields on line $.\n"; exit; } for my $f (0..$#fields) { # loop through all fields unless ($fields[$f] =~ $regexes[$f]) { # regex match print "invalid field on line $., field ", ($f+1), "\n"; exit; } } } 

Si vous enregistrez le script sous le nom valid.pl et que vous le rendez exécutable chmod +x valid.pl , vous pouvez l’appeler comme ./valid.pl filename . Actuellement, le script sortira dès que le premier problème sera rencontré. Si vous supprimez les instructions de exit , tous les problèmes liés au fichier seront répertoriés.

Si vous n’êtes pas familier avec perl, $. est une variable spéciale qui contient le numéro de ligne dans la boucle while. $#fields est la valeur du dernier index du tableau @fields , donc les 0..$#fields équivalent à la liste 0,1, …, 19. Les index de tableau commencent à 0, j’ai donc ajouté 1 au numéro du champ.