Forum Programmation.shell besoin d'aide pour un script : extraire un nombre et le réutiliser

Posté par  . Licence CC By‑SA.
Étiquettes :
2
10
jan.
2024

Bonjour à tous,

Je suis une brêle en script (et en plein d'autres choses) et je sollicite votre aide !

Contexte : j’utilise au collège un vidéoprojecteur interactif Epson branché sur mon portable en bureau étendu. Pour que le stylet tactile ne prenne en compte que la surface du VPI et non pas tout le bureau je fais les bidouilles suivantes :

    christian@cthulhu:~$ xinput
    ⎡ Virtual core pointer                        id=2    [master pointer  (3)]
    ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
    ⎜   ↳ MSFT0001:01 2808:0101 Mouse               id=12   [slave  pointer  (2)]
    ⎜   ↳ MSFT0001:01 2808:0101 Touchpad            id=13   [slave  pointer  (2)]
    ⎜   ↳ HID 04b3:310d                             id=9    [slave  pointer  (2)]
    ⎜   ↳ EPSON EPSON EPSON 695Wi/695WT Mouse       id=16   [slave  pointer  (2)]
    ⎜   ↳ EPSON EPSON EPSON 695Wi/695WT             id=17   [slave  pointer  (2)]
    ⎜   ↳ EPSON EPSON EPSON 695Wi/695WT Mouse       id=18   [slave  pointer  (2)]
    ⎜   ↳ EPSON EPSON EPSON 695Wi/695WT Mouse       id=19   [slave  pointer  (2)]
    ⎣ Virtual core keyboard                       id=3    [master keyboard (2)]
        ↳ Virtual core XTEST keyboard                 id=5    [slave  keyboard (3)]
        ↳ Power Button                                id=6    [slave  keyboard (3)]
        ↳ Video Bus                                   id=7    [slave  keyboard (3)]
        ↳ Power Button                                id=8    [slave  keyboard (3)]
        ↳ Integrated Camera: Integrated C             id=11   [slave  keyboard (3)]
        ↳ Ideapad extra buttons                       id=14   [slave  keyboard (3)]
        ↳ AT Translated Set 2 keyboard                id=15   [slave  keyboard (3)]
        ↳ AVerVision F17+                             id=10   [slave  keyboard (3)]

puis

    christian@cthulhu:~$ xinput map-to-output 16 HDMI-1
    christian@cthulhu:~$ xinput map-to-output 17 HDMI-1
    christian@cthulhu:~$ xinput map-to-output 18 HDMI-1
    christian@cthulhu:~$ xinput map-to-output 19 HDMI-1

Très content d'avoir trouvé ça (pas tout seul, c'est adapté de problèmes de tablettes tactiles et de graphistes utilisant GIMP sur deux écrans) je me suis dit « Facile, je fais un script et un raccourci sur le bureau. Je branche, je clique et ça roule »

    #!/bin/sh
    xinput map-to-output 16 HDMI-1
    xinput map-to-output 17 HDMI-1
    xinput map-to-output 18 HDMI-1
    xinput map-to-output 19 HDMI-1

Sauf que… ça marche pas toujours.

Les valeurs 16 17 18 et 19 sont parfois 10 16 17 et 18 ou 15 16 17 18 etc. Ça semble dépendre de l'ordre de branchement et de l'état (allumé ou éteint) des différents périphériques, de la météo et de l'âge du capitaine.

Mes cinq lignes ci-dessus n'étant pas loin de la limite actuelle de mes compétences en script, j'aimerai un peu d'aide (pas forcément un script tout fait, je préfère apprendre un peu) pour savoir comment extraire les 4 valeurs qui vont bien de la commande xinput puis comment les réutiliser pour les 4 commandes xinput map-to-output.

Merci d'avance

  • # Avec un Grep

    Posté par  . Évalué à 1.

    xinput | grep EPSON | grep -oP '(?<=id=)[0-9]+'
    
    • [^] # Re: Avec un Grep

      Posté par  (site web personnel) . Évalué à 2.

      Ça en fait deux. ;p

      (Une) version Perl : perl -ne 'print "$1\n" if /EPSON .* id=(\d+)/'

      Debian Consultant @ DEBAMAX

      • [^] # Re: Avec un Grep

        Posté par  . Évalué à 2.

        Nul doute qu'il y a autant de solutions que de linuxfriens  ;-)

    • [^] # Re: Avec un Grep

      Posté par  . Évalué à 2.

      christian@cthulhu:~$ xinput | grep EPSON | grep -oP '(?<=id=)[0-9]+'
      16
      17
      18
      19
      

      Je me doutais bien que grep viendrait à la rescousse mais pas deux fois ;-)

      Ça liste les valeurs à utiliser mais comment les réutiliser ensuite ?

      j'ai essayé (sur un malentendu ça peut passer) de les mettre dans un tableau :

      declare -a tableau(xinput | grep EPSON | grep -oP '(?<=id=)[0-9]+')
      

      mais non :

      bash: erreur de syntaxe près du symbole inattendu « ( »
      
      • [^] # Re: Avec un Grep

        Posté par  (site web personnel, Mastodon) . Évalué à 3.

        j'ai essayé (sur un malentendu ça peut passer) de les mettre dans un tableau :

        Et avec (pas testé) :

        declare -a tableau( $( xinput | grep EPSON | grep -oP '(?<=id=) [0-9]+' ) )
        
  • # avec sed

    Posté par  . Évalué à 3.

    Bonjour

    En utilisant sed pour extraire l'ID
    et une boucle for pour lancer les commandes map-to-input

    for id in $(xinput | sed -n '/EPSON EPSON EPSON 695Wi\/695WT/s/.*id=\([0-9]*\).*/\1/p'); do xinput map-to-output $id HDMI-1; done

  • # Pour les utiliser ensuite

    Posté par  . Évalué à 4.

    Tu peux soit faire une boucle for comme ci-dessus soit utiliser xargs
    xinput | grep EPSON | grep -oP '(?<=id=)[0-9]+' | xargs -I % xinput map-to-output % HDMI-1

    • [^] # Re: Pour les utiliser ensuite

      Posté par  . Évalué à 1.

      Cette ligne de commande fonctionne et j’arrive même à en comprendre le principe !

      J’ai été un peu à la bourre hier, je testerai les autres pistes la semaine prochaine. En tout cas merci à tous

  • # Merci pour la question

    Posté par  . Évalué à 2.

    Je cherchais à résoudre exactement le même problème hier, même pas besoin de chercher …
    Merci aussi aux répondants.

  • # awk et cut

    Posté par  (Mastodon) . Évalué à 4. Dernière modification le 10 janvier 2024 à 14:27.

    Moi j'ai mes habitudes avec awk et cut (voire tr mais là il n'y en a pas besoin)

    Ça devrait ressembler à qqchose comme :

    xinput | awk '/EPSON/{for (i=1 ; i<=NF ; i++) {if ($i~/=/) print $i}}' | cut -d '=' -f 2

    En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: awk et cut

      Posté par  . Évalué à 3. Dernière modification le 10 janvier 2024 à 18:24.

      Il y a aussi :

      xinput | awk '/EPSON/ { gsub(/.*id=| \[.*/,""); print }'

  • # Merci pour tout ça...

    Posté par  . Évalué à 1.

    Merci pour tout ça, je vais essayer de tester les différentes propositions demain (pas de VPI chez moi, ma petite dame n'apprécierait pas) et je reviendrai pour les questions suivantes  ;-)

  • # Que du bash

    Posté par  . Évalué à 4. Dernière modification le 11 janvier 2024 à 10:38.

    (Puisque c'est un script et pas une ligne de commande à la volée, autant ne faire que du shell (bash chez moi))

    J'ai fait un copier-coller de ton résultat de xinput dans un fichier nommé ficforum
    et un script stylet.bash :

    while read enreg
    do
        if [[ $enreg =~ 'EPSON EPSON EPSON 695Wi/695WT '([Mouse ]*)'id='([^ ]*) ]]
        then
        echo ${BASH_REMATCH[2]}
        fi
    done < ficforum
    ./stylet.bash
    16
    17
    18
    19

    Si ce test marche chez toi, y a plus qu'à remplacer
    echo ${BASH_REMATCH[2]}
    par
    xinput map-to-output ${BASH_REMATCH[2]} HDMI-1

    Améliorable, consolidable…

  • # concis et propre...

    Posté par  (site web personnel, Mastodon) . Évalué à 1.

    Mieux vaut tard que jamais ^

    xinput | awk -F'id=| +' '/EPSON/{print $(NF-3)}'
    16
    17
    18
    19
    

    On ne peut pas mettre d'array dans le string...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.