IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Opération sur chaque ligne d'un fichier style find avec les fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 51
    Par défaut Opération sur chaque ligne d'un fichier style find avec les fichiers
    Bonjour,

    J'ai dans un fichier des données entières rangées par colonne et séparées par le caractère ':'.
    Je peux facilement récupérer ces données via cut, c'était le but de la manip, maintenant j'aimerais pouvoir multiplier chacune des colonnes par une constante, il y a-t-il une commande pour ça ?
    Xargs semble presque faire l'affaire mais je crois qu'il est plutôt fait pour récupérer une liste d'arguments pour une seule commande.

    Merci

  2. #2
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 417
    Par défaut
    Bonjour,
    Une solution en awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ VAR=4 ; echo "5;2;9" | awk -F\; -vVAR=$VAR '{OFS=FS;while((i+=1) <= NF){$i=$i*VAR;}}1'
    20;8;36
    Une version sed pour le fun:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    VAR=4 ; echo "5;2;9" | sed -e 's/[0-9]*/$((&*'$VAR'))/g;s/;/";"/g;s/.*/echo -n &/e'
    20;8;36

  3. #3
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    et une Perl, for fun too :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ VAR=4
    $ echo "5;2;9" | perl -lne 'print join(";", map('$VAR'*$_, split(";", $_)))'
    20;8;36

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 51
    Par défaut
    Waw, il va me falloir un petit peu de temps avant de comprendre tout ça !
    Merci beaucoup.

  5. #5
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 723
    Par défaut
    c'est quoi « un fichier style find » ?
    quel rapport entre « un fichier des données entières rangées par colonne et séparées par le caractère ':' » et find ?

    j'aimerais pouvoir multiplier chacune des colonnes par une constante,
    c'est aussi faisable en shell : Comment lire/parcourir un fichier, mais ce sera plus lent.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 51
    Par défaut
    J'admet que le titre est un peu brut !
    "Style find" c'est plutôt appliquer une opération sur chaque élément trouvé, comme find peut appliquer des operations à chaque fichier qu'il touve, sauf qu'ici les éléments sont des données lues dans un fichier.
    La version awk semble plus simple, même si la syntaxe me paraît mystique, des suggestions pour apprendre awk ?

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 417
    Par défaut
    Voici une version pur bash:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ cat toto.txt 
    2;3;5
    3;4;6
     
    $ multi_by(){ VAR=$1 ; XX="" ;[ $2 -ne 0 ] && for i in ${MAPFILE[$(($2-1))]//\;/ } ; do echo -n "$XX$((i*VAR))";XX=";"; done ; echo ;} ;  mapfile -t -c 1 -C "multi_by 4"  <toto.txt 
     
    8;12;20
    12;16;24
    Celle-ci passe par la création d'une fonction qui écrit au format indenté donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    multi_by(){
      VAR=$1
      XX=""
      [ $2 -ne 0 ] && for i in ${MAPFILE[$(($2-1))]//\;/ }
      do
        echo -n "$XX$((i*VAR))"
        XX=";"
      done
      echo
    }
    Et ensuite on l'appelle en lui passant la valeur multiplicative (4 dans l'exemple) et via la builtin mapfile pour lui fournir directement les données ligne par ligne du fichier toto.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mapfile -t -c 1 -C "multi_by 4"  <toto.txt
    Ici, comme on peut le voir, nous encadrons de guillemets la fonction d'appel avec l'argument multiplicateur, ce qui fait que mapfile mettra l'indexage du tableau dans $2 au lieu de $1 et la valeur courante de la ligne lu dans $3.
    D'ailleurs, on peut très bien ne pas passer par le tableau MAPFILE, ce qui donnerait une fonction multi_by plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    multi_by(){
      VAR=$1
      XX=""
      VAL=$3
      for i in ${VAL//\;/ }
      do
        echo -n "$XX$((i*VAR))"
        XX=";"
      done
      echo
    }
    Celle-ci est plus simple, car le fait de passer par le tableau MAPFILE, nous sommes obligé de lire la ligne précédente et non courante, car celle-ci (ligne courante) ne sera insérée dans le tableau qu'a la sortie de la fonction.

  8. #8
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    une autre, toujours en bash, toujours for fnu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    s="$1"  # un choix comme un autre...
    delim=";"
    value=4
     
    read -a tab <<< "${s//$delim/ }"   # on nourrit le tableau avec les valeurs séparées par des espaces
    for i in ${tab[*]}; do
       r="${r}$(( i * value ))${delim}"  # on calcule et on rajoute à la chaine intermédiaire
    done
    echo ${r/%$delim/}  # avant d'afficher on retire le dernier délimiteur, effet de bord de la boucle

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/09/2009, 23h43
  2. Réponses: 5
    Dernier message: 27/08/2009, 15h51
  3. Réponses: 22
    Dernier message: 10/02/2007, 13h02
  4. effectuer une opération sur chaque ligne d'un select
    Par Mindiell dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 20/12/2006, 13h23
  5. [vb.net][dataView] test sur chaque lignes
    Par arnolem dans le forum Windows Forms
    Réponses: 2
    Dernier message: 10/02/2006, 11h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo