Bash : manipulation de tableaux

Résolu
arscy -  
arscy Messages postés 196 Statut Membre -

Bonjour,

Je suis en train de découvrir les tableaux sur bash et je ne saisis pas bien la manipulation des colonnes.
Illustration :
Je souhaite afficher le nom de tous les fichiers qui se trouvent dans un répertoire qui a été entré en paramètre (par exemple)
--> la commande ls -l devrait faire l'affaire, et je trouve le nom du fichier/répertoire en 8e colonne.
Du coup je pensais faire quelque chose du style :

#$1 == nom du répertoire exploré

tab=`ls -l ${1}` #constitution d'un tableau avec un fichier par ligne (+ extra infos)
for fic in tab #parcours de chaque ligne
do
   if [ -d $fic[7] ]; #7e colonne = nom de fichier/répertoire
   then 
      echo "nom du fichier : ${fic[7]}" #afficher le nom
   fi
done 

Sans surprise, ça ne fonctionne pas (sinon je ne poserais pas la question, uh).

À partir de cette illustration sauriez-vous m'orienter s'il vous plaît?
(j'ai trouvé une alternative à l'utilisation du tableau via des grep et des cut notamment, mais je pense que c'est faisable via un tableau, en plus simple en fin de compte).

Merci d'avance pour votre temps!

2 réponses

  1. Flachy Joe Messages postés 2303 Statut Membre 261
     

    Salut !

    Il faut spécifier correctement le séparateur de liste

    #$1 == nom du répertoire exploré
    
    # on spécifie de couper aux sauts de ligne uniquement
    IFS=$'\n'
    for line in $(ls -l ${1}) #pour chaque ligne
    do
        # on crée une liste en coupant aux espaces
        IFS=$' ' read -ra liste <<< "$line"
        echo "nom du fichier : ${liste[@]:8}" #afficher le 8eme élément (on compte à partir de 0) et les suivants
    done
    
    # attention de rétablir le séparateur par défaut pour la suite du script
    IFS=$' \t\n'

    Comme il peut y avoir des espaces dans les noms de fichier, il faut afficher toute la fin de la ligne à partir de l'élément 8.


    1
    1. arscy
       

      donc le concept serait de réaliser une matrice en 2D?
      D1 : la liste des fichiers
         D2 : chaque élément de la liste

      Ne pourrais-je pas partir directement en un
       

      $d1=(`ls l-`)
      for line in $d1
      do
         elt=($line)
         echo "nom de fichier : ${elt[7]}"
      done
      0
  2. Flachy Joe Messages postés 2303 Statut Membre 261
     

    Non car ta variable $d1 serait découpée par les sauts de lignes, les tabulations et les espaces, tu te retrouverais avec un tas de mots et pas des lignes.

    Essaye un

    echo $line

    dans ta boucle, tu verras bien que tu obtiens chaque mot séparément.

    NB1 : il est conseillé d'utiliser la syntaxe $(commande) plutôt que `commande` pour les sous-shell.

    NB2 : tu peux débuguer ton script en le lançant avec

    bash -x mon_script.sh

    0
    1. arscy Messages postés 196 Statut Membre 8
       

      Je constate en effet que je n'obtiens pas le résultat escompté :-(
      Une dernière question avec la fameuse syntaxe $(commande)
      j'ai du mal à percevoir la différence entre

      for element in $var


      et

      for element in $(`commande`)


      → Quelle est la différence fondamentale?
      Parce que je n'ai pas l'impression de voir une différence cruciale entre

      var=`ls -a`


      et
       

      var=(`ls -a`)

      par exemple

      0
      1. Flachy Joe Messages postés 2303 Statut Membre 261 > arscy Messages postés 196 Statut Membre
         

        La différence entre `` et $() est bien expliquée (en anglais) ici https://www.redhat.com/sysadmin/backtick-operator-vs-parens et là https://yeahexp.com/what-is-dollar-followed-by-parentheses-for-in-bash/

        En deux mots :

        • $() est plus lisible (pas de confusion avec ' ')
        • $() est imbriquable sans caractère d'échappement

        EDIT : attention on ne met pas les accents graves dans les $().

        0
      2. arscy Messages postés 196 Statut Membre 8 > Flachy Joe Messages postés 2303 Statut Membre
         

        merci beaucoup pour ces informations !
        je pensais que le $() était réservé aux tableaux/listes :-S

        0