Bash : Lire colonne .dat jusque...

Bonjour,

Cela fait deux bonnes heures que je galère pour un problème somme toute assez simple... J'essaie d'extraire des données (pour en calculer moyenne et variance) d'un fichier .dat donc la structure est comme suit:
De la 1ère à la n_ème ligne il y a des colonnes séparées par des tab et qui contiennent des nombres (parfois entiers, parfois float, parfois négatifs etc), et sur la fin du fichier une sorte de "petit résumé" qui commence par une ligne bien définie (Reactor stats:)

Je cherche donc à lire en shell (korn shell ou bash, peu importe les nuances)ces données. Voici ce que j'ai déjà écrit et qui ne marche qu'à moitié:

#!/bin/bash
fichier=$1
colonne=$2
while read ligne
do
        if [ grep Reactor $ligne!='' ] ;then
                echo $ligne | awk '{ print $'$colonne' }'
        else
                break
        fi
done < $fichier

11 réponses

  • Votes
  • Date
  • Date décroissante
  1. Mon fichier contient bel et bien des tab et non des espaces, je ne savais juste pas comment les écrire dans la fenêtre.

    Je ne peux pas vous donner le "vrai" fichier, simplement parce qu'il contient des données classifiées. (ce serait sans incidence mais la règle, c'est la règle :-) )

    Je vais déjà essayer de me débrouiller avec tout ça. Merci pour votre aide.
    1. Modérateur
      Re,

      Mon fichier contient bel et bien des tab et non des espaces, je ne savais juste pas comment les écrire dans la fenêtre.
      Je le crois bien, je parlais de l'exemple ;-)

      simplement parce qu'il contient des données classifiées.
      Pas de problèmes, je comprends ;-)
      Quand on essaie de trouver une solution sans avoir exactement les données en entrée c'est plus difficile.
  2. Modérateur
    Re,

    J'ai repris ton exemple mais j'ai remplacé les espaces avec une tabulation
    Dans ton fichier il y a une seule ligne qui contient Reactor ou plusieurs.
    Puisque si c'est le cas alors il faut nous donner un exemple de fichier et si possible avec la bonne structure.

    $ cat -A plop
    1^I$
    2^I$
    3^I3241^I-2$
    4^I2384^I4$
    5^I8594^I-5$
    6^I2348^I87$
    7^I2938^I3$
    $
    Reactor^Istats:^I$
    ^IAxial^Ibalblalba$
    ^IPoints:^I63$
    $
    $ cat plop
    1	
    2	
    3	3241	-2
    4	2384	4
    5	8594	-5
    6	2348	87
    7	2938	3
    
    Reactor	stats:	
    	Axial	balblalba
    	Points:	63
    $ awk -F"\t" 'FNR==1,/Reactor/{if($3)i+=1;somme+=$3}END{ print "somme = " somme ", moyenne = " somme/i}' plop
    somme = 87, moyenne = 17.4

    1. Modérateur
      Re,

      Attention ton exemple a comme séparateur espace pas tabulation
      $ cat plop 
      1          
      2          
      3     3241     -2
      4     2384     4
      5     8594     -5
      6     2348     87
      7     2938     3
      
      Reactor stats: 
                          Axial balblalba
                          Points: 63
      $ awk 'FNR==1,/Reactor/{if($3)i+=1;somme+=$3}END{ print "somme = " somme ", moyenne = " somme/i}' plop
      somme = 87, moyenne = 17.4

      1. Modérateur
        Re,

        Peut tous nous donner ton fichier ou une partie pour tester?

        Edit:
        Oups, je n'ai pas vu que tu as donnée un exemple ;-)
        1. @lami : après test, ça ne marche pas vraiment... il ne s'arrête pas de lire à la ligne "reactor" et donc la moyenne est biaisée.

          J'ai également oublié de stipuler que le remplissage de la colonne à lire ne commence pas toujours à la ligne 1.

          Voici à quoi ressemble le fichier:
          1          
          2          
          3     3241     -2
          4     2384     4
          5     8594     -5
          6     2348     87
          7     2938     3
          
          Reactor stats: 
                              Axial balblalba
                              Points: 63
          
          1. @dubcek, non justement, les données qui sont situées au-dessus.

            Merci lami, je vais regarder ça! Ca a une bonne tête ;).
            1. Modérateur
              Salut,

              Attention à la syntaxe aussi !!!

              if [ grep Reactor $ligne!='' ]


              Il faut des espaces de part et d'autre du signe égalitaire (ou non-égalitaire dans ton cas).
              Ensuite la syntaxe de ta commande dans le test doit être entourée par "$(commande)"
              La redirection de la variable doit être induite par <<< :

              if [ $(grep 'Reactor' <<< ${ligne})" != '' ]

              1. Modérateur
                Re,

                Pour la moyenne par exemple
                $ awk -F"\t" '$0!~/^$/ {i+=1;somme+=$2}END{ print "somme = " somme ", moyenne = " somme/i}' plop
                somme = 130, moyenne = 65
                
                ou
                $ awk -F"\t" '{somme+=$2}END{ print "somme = " somme ", moyenne = " somme/NF}' plop
                somme = 130, moyenne = 65


                1. Contributeur
                  hello
                  tu veux extraire la colonne x de la ligne qui contient Reactor ?
                  $ cat a1
                   1 2 3
                   1 2 3
                   1 2 3
                   1 2 3
                  Reactor 4 5 6 
                  $ head f1
                  #!/bin/bash
                  
                  fichier=$1
                  colonne=$2
                  awk '/Reactor/ {print $'"$colonne"'}'  $1
                  
                  $ ./f1 a1 3
                  5
                  $ 
                  
                  
                  1. Il s'arrêtera à la ligne "Reactor stats"? J'imagine que non. C'est surtout ça mon problème.
                    1. Modérateur
                      Salut,

                      Edit :

                      Tu connais le numéro de champ et le séparateur, alors pourquoi pas tout simplement.
                      $ cat plop 
                      q1	50
                      q2	80
                      $ awk -F"\t" '{somme+=$2}END{ print somme}' plop
                      130