#1 Le 18/03/2017, à 18:44
- LionelAllorge
Sélectionner un fichier au hasard dans un répertoire
Bonjour,
J'essaye, avec un script, de sélectionner un fichier au hasard dans un répertoire. Je peux avoir la liste des fichiers facilement avec "ls" mais, ensuite, comment ne prendre d'une ligne au hasard dans le résultat ?
Merci d'avance.
Lionel Allorge
Administrateur de l'April : http://www.april.org/
Président de la LuneRouge : http://www.lunerouge.org/
Membre de Wikimedia France : http://www.wikimedia.fr//
Hors ligne
#2 Le 18/03/2017, à 18:53
- pingouinux
Re : Sélectionner un fichier au hasard dans un répertoire
Bonjour,
fichier=$(ls | shuf -n1)
Hors ligne
#3 Le 18/03/2017, à 18:55
- Watael
Re : Sélectionner un fichier au hasard dans un répertoire
salut,
d'abord, utiliser ls autrement que pour en lire le résultat est rarement une bonne pratique.
il est préférable d'utiliser les globs (voir Motifs génériques dans le man bash), dans un tableau, et d'appeler RANDOM modulo le nombre d'éléments du tableau +1.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#4 Le 19/03/2017, à 10:58
- Hizoka
Re : Sélectionner un fichier au hasard dans un répertoire
Salut, ne connaissant pas la commande shuf j'aurais fait comme l'indique Watael :
fichiers=(${HOME}/*) # Mais ça renvoie tous les items
aleat=$(( ${RANDOM} % (${#fichiers} + 1) ))
echo "${fichiers[${aleat}]}"
et avec shuf :
fichiers=(${HOME}/*) # Mais ça renvoie tous les items
shuf -n 1 <<< echo -e "${fichiers[@]}"
et si on ne veut que les fichiers :
fichiers=($(find ${HOME} -type f)) # Ca ne renvoie que les fichiers en mode recusrif, s'il ne faut que le fichier -maxdepth 1
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#5 Le 19/03/2017, à 12:23
- credenhill
Re : Sélectionner un fichier au hasard dans un répertoire
hello
t=(*); echo ${t[((RANDOM*${#t[@]}/32767))]}
Hors ligne
#6 Le 19/03/2017, à 12:34
- Watael
Re : Sélectionner un fichier au hasard dans un répertoire
8O
qu'est-ce que "32767" ?
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#7 Le 19/03/2017, à 13:50
- credenhill
Re : Sélectionner un fichier au hasard dans un répertoire
la valeur max. de $RANDOM
est ce faux sur un système 64 bits ?
Hors ligne
#8 Le 19/03/2017, à 14:09
- Watael
Re : Sélectionner un fichier au hasard dans un répertoire
non, c'est propre à bash, et indépendant de la machine.
mais le shell ne gère pas les nombres à virgule, donc si ${#t[@]} n'est pas un mutiple de 32767, on tombera toujours sur le premier élément du tableau : ${t[0]}
et, tant que je suis là, tableau=( $(find ...) )pose les mêmes problèmes que ls les noms de fichiers comportant des caractères de l'IFS seront scindés en éléments.
pour utiliser find pour créer un tableau, il faut parcourir sa sortie avec une boucle while.
while read -r -d '' line; do tableau+=( "$line" ); done < <(find ... print0)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#9 Le 20/03/2017, à 14:11
- credenhill
Re : Sélectionner un fichier au hasard dans un répertoire
mais le shell ne gère pas les nombres à virgule, donc si ${#t[@]} n'est pas un mutiple de 32767, on tombera toujours sur le premier élément du tableau : ${t[0] ]
une division non entière ne retoune pas 0 mais l'entier inférieur
$ ls
a b c d e f g h i j k l m n o p q r s t u v w x y z
$ for x in {1..10}; do t=(*); echo ${t[$(($RANDOM*${#t[@]}/32767))]}; done
j
g
m
j
y
b
j
o
p
g
$
Hors ligne
#10 Le 20/03/2017, à 14:34
- LeoMajor
Re : Sélectionner un fichier au hasard dans un répertoire
j'aime bien shuf, plutôt sympa
Sélectionner un fichier au hasard dans un répertoire
shuf -n1 < <(find . -maxdepth 1 -type f -exec realpath {} \;)
shopt -s globstar; shuf -n1 < <(printf "%s\n" ** )
"Sélectionner un dossier au hasard dans une arborescence"
shopt -s globstar; shuf -n1 < <(printf "%s\n" **/ )
Hors ligne
#11 Le 20/03/2017, à 20:02
- Watael
Re : Sélectionner un fichier au hasard dans un répertoire
une division non entière ne retoune pas 0 mais l'entier inférieur
si ${#t[@]} n'est pas un multiple de 32767, on tombera toujours sur le premier élément du tableau : ${t[0]}
j'aurais dû préciser "un multiple supérieur à 32767"
$ touch {a..z}
$ ls
a b c d e f g h i j k l m n o p q r s t u v w x y z
$ t=(*)
$ for i in {1..10}; do echo ${t[$((RANDOM*(${#t[*]}/32767)))]}; done
a
a
a
a
a
a
a
a
a
a
EDIT: ah, j'ai compris pourquoi ma commande ne fonctionne pas comme la tienne : j'ai ajouté des parenthèses pour exécuter la division avant la multiplication. « forcément, [ça] va marcher beaucoup moins bien ! »
Dernière modification par Watael (Le 20/03/2017, à 20:02)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne