#1 Le 23/04/2011, à 14:57
- Sarya
Comment effectuer une tache sur le premier fichier d'un dossier ?
Bonjour !
Je réalise un petit script de tri de fichier en fonction de leur type, qui déplace les fichiers dans les dossiers correspondants, créés au préalable.
Je pensais faire une boucle while du genre "temps que le nombre de fichier présents n'est pas 0, fait ça :"
et puis après coller un if pour le triage proprement dit.
Le problème c'est que qu'en entrée de ma boucle if il me faudrait un fichier, le premier de mon dossier, mais je sais pas du tout comment l'appeler. Pour le moment voilà ce que j'ai :
n=ls -1 | wc -l #comptage du nombre de fichiers dans le dossier courant
while [ "$n" != "0" ]
do
file "fichier"
read ext
if [ "ext" = "music" ]; then
{
mv "fichier" Music
}
elif .... #etc avec les autres types de fichiers (Vidéos,Images,Autres...)....
fi
od
exit 0
Voilà, mon problème est donc d'appeler "fichier" dans l'instruction file. Je me fout de savoir lequel il prend, je veux qu'il en prenne un et qu'il le déplace comme il faut... Des idées ?
Par ailleurs, par rapport à l'instruction file, qui est celle que j'ai trouvé pour détecter le type de fichier, la sortie est assez longue et je ne suis pas sûr que ce soit la meilleure façon de sélectionner les fichier d'après leur types, surtout pour comparer ça a autre chose dans le "if"... (je suis pas sûr de bien me faire comprendre
Anyway, si quelqu'un entend cet appel au secours et y répond, je lui en serait éternellement reconnaissant
Hors ligne
#2 Le 23/04/2011, à 15:30
- aduxas
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
As-tu considéré
for file in *; do ...; done
Hors ligne
#3 Le 23/04/2011, à 17:21
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Et ce n'est pas
while cond; do
od
mais
while cond; do
done
D'autre part au lieu d'enchainer des elifs, tu devrais utiliser "case".
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#4 Le 24/04/2011, à 21:55
- Levi59
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Essaye ceci (Code à compléter):
## DOSSIERS
IMAGES="/chemin/vers/dossier/images"
VIDEOS="/chemin/vers/dossier/videos"
AUDIO="/chemin/vers/dossier/audio"
etc
while read
do
EXT="${REPLY##*.}"
case "${EXT}" in
avi|mpeg) DEST="${VIDEOS}";;
jpg|png) DEST="${IMAGES}";;
mp3|ogg) DEST="${AUDIO}";;
etc
*) echo "Format inconnu" ; exit ;;
esac
mv "${REPLY}" "${DEST}"
done < <(ls)
Hors ligne
#5 Le 29/04/2011, à 13:44
- Sarya
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Super ! Avec tout ça je devrais arriver à faire un truc qui fonctionne !!
Merci à tous !
Hors ligne
#6 Le 01/05/2011, à 22:28
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
http://partmaps.org/era/unix/award.html
De plus, sous Linux ya plus évolué que se baser sur l'extension des fichiers. Si tu enregistre un tag.gz en .zip, est-ce que ton script va bien le gérer ?
Tu te limite au dossier courant. Ma version gere n'importe quel (suite d') argument(s), ex :
./script ~/*.jpg ~/*.pdf /path/elsewhere/*
Solution largement commentée :
#!/bin/bash
# made by sputnick 20110501
# Version du script de Levi59 amélioré -> http://forum.kubuntu-fr.org/viewtopic.php?id=456701
## DOSSIERS
IMAGES="/chemin/vers/dossier/images"
VIDEOS="/chemin/vers/dossier/videos"
AUDIO="/chemin/vers/dossier/audio"
# AUTRES A COMPLETER...
# pas besoin de faire "for F in; do",
# bash va lire directement les fichiers
# donnés en paramètre.
for F; do
go=true
# on utilise directement la sortie de la commande file
# pour chercher son vrai type
# indépendamment de l'extension.
# Voir "man 1 file"
case $(file "$F") in
*Video*) DEST="${VIDEOS}";;
*image*) DEST="${IMAGES}";;
*Audio*) DEST="${AUDIO}";;
# a completer, faire "file <FICHIER>" pour voir son type...
*) go=false; echo >&2 "Format inconnu pour ${F}" ;;
esac
# -i demande confirmation avant d'écraser un fichier
[[ $go = true ]] && mv -i "${F}" "${DEST}"
done
Dernière modification par sputnick (Le 01/05/2011, à 22:35)
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#7 Le 01/05/2011, à 23:08
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
La dernière solution que j'ai donnée est pour tous les fichiers en arguments avec le système des globs.
Cette nouvelle version est conforme à la spec, à savoir gérer uniquement le premier fichier des répertoires donnés en argument.
#!/bin/bash
# made by sputnick 20110502
# Version du script de Levi59 amméllioré -> http://forum.kubuntu-fr.org/viewtopic.php?id=456701
## DOSSIERS
IMAGES="/chemin/vers/dossier/images"
VIDEOS="/chemin/vers/dossier/videos"
AUDIO="/chemin/vers/dossier/audio"
# AUTRES A COMPLETER...
# pas besoin de faire "for REP in; do",
# bash va lire directement les répertoires
# donnés en paramètre.
for REP; do
c=0
go=true
if [[ ! -d "${REP}" ]]; then echo >&2 "${REP} n'est pas un repertoire tudjuuu ! On quitte..."; exit 1; fi
# on utilise un array (tableau, matrice) pour pouvoir
# traiter le premier fichier du répertoire
ARR=( ${REP}/* )
# tant que l'on ne trouve pas un fichier (au lieu d'un sous répertoire),
# on boucle et on itère le compteur $c
while [[ ! -f "${ARR[c]}" && -e "${ARR[c]}" ]]; do ((c++)); done
# si le while a trouvé un fichier ok,
# sinon on switch de répertoire
[[ -f "${ARR[c]}" ]] || continue
# on utilise directement la sortie de la commande file
# pour chercher son vrai type
# indépendamment de l'extension.
# Voir "man 1 file"
case $(file "${ARR[c]}") in
*Video*) DEST="${VIDEOS}";;
*image*) DEST="${IMAGES}";;
*Audio*) DEST="${AUDIO}";;
# a completer, faire "file <FICHIER>" pour voir son type...
*) go=false; echo >&2 "Format inconnu pour ${ARR[c]}" ;;
esac
# -i demande confirmation avant d'écraser un fichier
[[ $go = true ]] && mv -i "${ARR[c]}" "${DEST}"
done
Dernière modification par sputnick (Le 01/05/2011, à 23:17)
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#8 Le 07/05/2011, à 10:39
- Levi59
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Retour après 10 jours d'absence
@sputnick
Ok ls n'était pas nécessaire mais mon code n'était pas vraiment fonctionnel, c'était juste un exemple à modifier. L'extension, c'est pas non plus la meilleur solution mais c'était la plus simple pour l'exemple, j'avais d'ailleurs déjà écrit un script de tri qui utilisait les types mimes donc ce n'était pas la peine de me sortir le golden award. Mon but était juste d'orienter Sarya sur une solution possible...
Hors ligne
#9 Le 07/05/2011, à 15:57
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
...ce n'était pas la peine de me sortir le golden award. Mon but était juste d'orienter Sarya sur une solution possible...
C'est de l'humour tu sais ?
C'est juste une extension de la culture Unix autour du célèbre http://partmaps.org/era/unix/award.html
On a tous à un moment T eu droit à des awards, moi y compris ^^
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#10 Le 07/05/2011, à 17:40
- Levi59
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Je n'étais ni énervé ni vexé, c'était juste pour préciser puisque dans ce cas je ne cherchais pas la perfection mais juste à être didactique.
Hors ligne
#11 Le 07/05/2011, à 18:03
- 01franz
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
bonsoir
merci le script peu tout-jour servir.
toujours utile
sudo tail -f /var/log/syslog
Hors ligne
#12 Le 07/05/2011, à 18:51
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Je n'étais ni énervé ni vexé, c'était juste pour préciser puisque dans ce cas je ne cherchais pas la perfection mais juste à être didactique.
Cool, tant que ya pas des horreurs comme des
for i in `ls`
qui BREAK les fichiers avec espaces, moi je dit rien
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#13 Le 07/05/2011, à 18:57
- 01franz
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
pour les espace une piste
for f in *; do
echo $f
file=$(echo $f | tr A-Z a-z | tr ' ' _ |tr '( ) , : / \ ; [ ] | » « ' _)
[ ! -f $file ] && mv "$f" $file
ls
done
toujours utile
sudo tail -f /var/log/syslog
Hors ligne
#14 Le 07/05/2011, à 19:06
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
NOPE, the reply must be "USE MORE QUOTES!"
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#15 Le 08/05/2011, à 13:55
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
J'avais une petite interrogation au sujet du for in ls.
Actuellement je bosse sur un menu déroulant non graphique en sh pour serveur, basé sur ncurses. Ca lance des commandes, ce sera donc à mi chemin entre des alias organisés et des listes de bookmarks.
Les menus (à remplir par l'utilisateur) sont des chemins de type :
/home/session/.qmenu/profileexemple_1_Q.qmenu
/home/session/.qmenu/profileexemple_2_Sytem.qmenu
...
/home/session/.qmenu/profileexemple_10_Power.qmenu
Soit en gros :
${PATH}/${PROFILE}_${ID}_${NAME}.qmenu
Les menus sont donc indexés. Lors du démarrage du programme, le profile en question est scanné et ré-indexé (par exemple si un menu a été supprimé manuellement dans le dossier .qmenu, l'index devient incohérent, il faut alors le réorganiser).
J'ai donc quelquechose du style :
...
ID=1
for M in $(\ls -1 -v "${HOME}"/.qmenu/${PROFILE}_*.qmenu 2>/dev/null); do
[ -f "$M" ] || continue
hash_menu "$M"
M_TARGET="${FOUND_PATH}/${FOUND_PROFILE}_${ID}_${FOUND_NAME}.${FOUND_EXT}"
status "Indexing : $(printf "%2s" "$ID") [ profile « $PROFILE » , menu « $FOUND_NAME » ]"
[ "$M_TARGET" = "$M" ] || mv "$M" "$M_TARGET"
etc......
ID=$(($ID+1))
done
Le "ls -v" conserve l'ordre naturel des nombres (de l'index, donc) ce qui me permet de réorganiser l'index en une suite cohérente d'entiers tout en conservant l'ordre original des menus.
Bien évidemment, cela ne gère donc pas les espaces, c'est pourquoi intervient la ligne :
[ -f "$M" ] || continue
Ce n'est pas très grave car les noms des menus ne sont pas sensés contenir des espaces (et j'en interdis la possibilité lors de la création d'un nouveau menu). Il n'en reste pas moins que c'est un méchant for in ls tout à fait inélégant... Et aussi j'aurais bien voulu que les profiles, eux, puissent contenir des espaces par exemple.
Donc, dans un cas comme celui-ci, quelle serait la solution pour se passer de ls (ou de for, ou de while ce qui revient au même) ? En sh bien sùr ?
Dernière modification par FRUiT (Le 08/05/2011, à 14:33)
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#16 Le 08/05/2011, à 14:00
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Et autre question, un nom de session linux peut-il ou non contenir un espace ?
Genre "/home/albert dupont/"
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#17 Le 08/05/2011, à 14:37
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
GASP ! Si tu relis le fil, j'explique que
for i in $(ls)
c'est la loose assurée.
Tu a besoin des globs pour ne pas créer le fameux "useless use of ls"
C'est archi simple :
for i in "${HOME}"/.qmenu/${PROFILE}_*.qmenu; do ...
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#18 Le 08/05/2011, à 14:41
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Oui mais si tu relis bien mon message, en reprenant ton exemple, le menu 10 va passer avant le menu 2 ............
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#19 Le 08/05/2011, à 14:58
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Je te conseille une autre convention de nommage (renommer en masse tes fichiers avec prename) du style :
00001
00002
...
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#20 Le 08/05/2011, à 15:45
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Mmm le problème c'est que ça m'obligerait a faire des printf "%02d" et/ou des découpages de variables partout dans le script... J'avais déjà envisagé cette possibilité je vais lui redonner une chance...
Dernière modification par FRUiT (Le 08/05/2011, à 15:49)
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#21 Le 08/05/2011, à 16:21
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Sinon au pire ya aussi cette solution :
for i in "${HOME}"/.qmenu/${PROFILE}_*[0-9] .qmenu "${HOME}"/.qmenu/${PROFILE}_*[0-9][0-9] .qmenu
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#22 Le 08/05/2011, à 17:01
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Plutôt comme ça :
for i in "${HOME}"/.qmenu/${PROFILE}_[0-9]_*.qmenu "${HOME}"/.qmenu/${PROFILE}_[0-9][0-9]_*.qmenu
Ca semble bien marcher après 2 ou 3 tests... Merci j'y avais pas pensé
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#23 Le 08/05/2011, à 17:17
- sputnick
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
Wé mais la solution de renommage reste quand même plus propre...
<?xml version="1.0" encoding="UTF-8"?>
https://sputnick.fr
Hors ligne
#24 Le 08/05/2011, à 17:54
- FRUiT
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
J'utilise beaucoup seq... Si y'a un moyen de lui faire énumérer 01 02 03 04 05, là je dis pas mais sinon, le coup des [1-9] et [1-9][0-9] me parait le plus rapide et utilisant moins d'outils. La rapidité étant un facteur déterminant dans ce script en particulier.
Je me limite (à part mv, cp et rm) à : tput, stty, seq, awk, ls.
Dernière modification par FRUiT (Le 08/05/2011, à 18:01)
Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
Hors ligne
#25 Le 08/05/2011, à 18:59
- aduxas
Re : Comment effectuer une tache sur le premier fichier d'un dossier ?
seq -f "%02.0f" 1 5
01
02
03
04
05
Hors ligne