Shell, bash afficher valeur manquant

Bonjour,

j'ai un fichier log.txt avec

bpc19;BC02;SLOT05
bpc20;BC02;SLOT06
bpc21;BC02;SLOT07
bpc22;BC02;SLOT08
bpc23;BC02;SLOT09
bpc24;BC02;SLOT10
bpc26;BC02;SLOT12
bpc27;BC02;SLOT13
bpc28;BC02;SLOT14
bdbm;BC01;SLOT00
bpc19;BC02;SLOT05
bpc20;BC02;SLOT06
bpc21;BC02;SLOT07
bpc22;BC02;SLOT08
bpc23;BC02;SLOT09
bpc24;BC02;SLOT10
bpc26;BC02;SLOT12
bpc27;BC02;SLOT13
bpc28;BC02;SLOT14
bdbm;BC01;SLOT00

et je veux récupéré les slot manquant 0,1,2,3,4,11 le code en bash est :

tableau=0

while read line
do

slot_number=$(echo "$line" | cut -d';' -f3 | cut -d'T' -f2 )
slot_number=$slot_number | bc
slot_number=${slot_number##0}

if [ $tableau = $slot_number ]
then
#tableau=$((1+tableau))
echo "ok"

else

tableau=$((1+tableau))

echo "tableau=$tableau"
echo "slot_number=$slot_number\n"

echo "not_ok"

fi

done < log.txt

je vous remercie d'avance pour vos réponses ;)

3 réponses

  • Votes
  • Date
  • Date décroissante
  1. Contributeur
    hello
    au choix
    $ unset t x; b=0; while read a; do n=${a##+(*SLOT)?(0)}; b=$((n>$b? $n: $b)); t[$n]=1; done < <(grep bpc log.txt)
    $ for ((; x<$b; x++)); do [[ -z ${t[$x]} ]] && printf "SLOT%02d\n" $x; done
    SLOT00
    SLOT01
    SLOT02
    SLOT03
    SLOT04
    SLOT11
    $ unset t x; b=0; while read a; do n=${a##+(*SLOT)?(0)}; b=$((n>$b? $n: $b)); t[$n]=1; done < log.txt
    $ for ((; x<$b; x++)); do [[ -z ${t[$x]} ]] && printf "SLOT%02d\n" $x; done
    SLOT01
    SLOT02
    SLOT03
    SLOT04
    SLOT11
    1. Contributeur
      Salut,

      $ cat fich
      bpc19;BC02;SLOT05
      bpc20;BC02;SLOT06
      bpc21;BC02;SLOT07
      bpc22;BC02;SLOT08
      bpc23;BC02;SLOT09
      bpc24;BC02;SLOT10
      bpc26;BC02;SLOT12
      bpc27;BC02;SLOT13
      bpc28;BC02;SLOT14
      bdbm;BC01;SLOT00
      bpc19;BC02;SLOT05
      bpc20;BC02;SLOT06
      bpc21;BC02;SLOT07
      bpc22;BC02;SLOT08
      bpc23;BC02;SLOT09
      bpc24;BC02;SLOT10
      bpc26;BC02;SLOT12
      bpc27;BC02;SLOT13
      bpc28;BC02;SLOT14
      bdbm;BC01;SLOT00


      $ ./script.sh
      SLOT00 manquant
      SLOT01 manquant
      SLOT02 manquant
      SLOT03 manquant
      SLOT04 manquant
      SLOT11 manquant


      Spoiler
      $ cat script.sh
      #! /bin/bash
      #set -x
      count=$(grep '^bpc' fich | sort -t';' -k3 -u | tail -1 | grep -Po '.*;SLOT\K.*$')

      for i in $(seq -f "%02g" 0 ${count})
      do
      grep -q "SLOT${i}\b" < <(grep -v 'bdbm' fich) || echo "SLOT${i} manquant"
      done < fich

      1. Modérateur
        Note que SLOT00 n'est pas manquant.
      2. Contributeur
        @mamiemandoSalut,

        Je cite glardz : et je veux récupéré les slot manquant 0,1,2,3,4,11 .

        Et :
        bpc28;BC02;SLOT14
        bdbm;BC01;SLOT00
      3. Modérateur
        Eh bé... si effectivement il faut en plus contrôler le premier champ, l'énoncé aurait pu être posé plus clairement. Mais merci pour ta remarque.
      4. Contributeur
        @mamiemandoSalut,

        C'est souvent le problème avec les demandes non-exhaustives, voire pas du tout dans certains cas ;-(
    2. Modérateur
      Tu peux extraire la liste des valeurs de slot ainsi :

      cat log.txt | cut -d";" -f3 | sort | uniq | sed -e 's/SLOT0*\([0-9]\+\)/\1/'


      Ensuite il suffit d'itérer sur ta place de valeur pour vérifier si c'est dans cette liste.

      #!/bin/bash
      
      if [ $# -ne 1 ]
      then
          echo "usage: $0 logfile"
          exit 1
      fi
      
      filename=$1
      if [ ! -f "$filename" ]
      then
          echo "$0: invalid path: $1"
          exit 1
      fi
      
      l=$(cat $filename | cut -d";" -f3 | sort | uniq | sed -e 's/SLOT0*\([0-9]\+\)/\1/')
      for x in $(seq 1 20)
      do
          found=0
          for i in $l
          do
              if [ "$x" -eq "$i" ]
              then
                  found=1
              fi
          done
          if [ $found -eq 0 ]
          then
              echo "$x not found"
          fi
      done
      exit 0


      On exécute :

      chmod a+x script.sh
      ./script.sh log.txt


      Ce qui donne :

      1 not found
      2 not found
      3 not found
      4 not found
      11 not found
      15 not found
      16 not found
      17 not found
      18 not found
      19 not found
      20 not found


      Notes :
      - la plage d'entiers testée (ici {1, 2, ... 20} et qui correspond aux valeurs passées à
      seq
      pourrait être passé en paramètre.
      - l'intersection entre les valeurs extraites de log.txt (ie
      $l
      ) et l'ensemble induit par
      seq 1 20
      peut être traité plus rapidement car dans les deux cas les valeurs sont triées dans l'ordre croissant, on peut donc adapter cet algorithme pour fonctionner en O(min(m,n)) au lieu d'O(m.n) avec m et n les tailles respectives des deux ensembles.

      Bonne chance