Précédent   Forum du club des développeurs et IT Pro > Systèmes > Linux > Shell et commandes GNU
Shell et commandes GNU Vos questions sur l'utilisation des commandes shell. Manuel Linux
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 23/11/2012, 14h04   #1
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Par défaut [shell] variable de recherche à partir d'une liste

Bonjour,

Voilà 2 jours que je cherche déjà de manière théorique et un peu en pratique sans grand succès pour mon faible niveau en shell, la manière de traiter une liste de fichier à partir d'une liste txt .

Je reçoit un fichier quotidien txt recensant des centaines (stock/nbr de vente...) de fichier sur une machine à trier actuellement...à la main.

Et en fonction de ces fichiers ils doivent être classé sur différentes partitions avec un dossier à créer ou, si déjà existant sur celles ci, simplement le déplacer.
Le gros hic est que je dois exclure les numéros et caractère speciaux présent dans la liste (fichier numéroté dans le nom et malheureusement ce n'est pas une date...) ou dans le cas contraires lire le contenu du répertoire d'arrivée.

les noms se présentes sous la forme suivante:
Stockcentralparis001
Stock externe 0054...
Journee_154_brest

Comme je recommence un script de zéro, j'ai déjà testé une fois dans le dossier principal de refaire une liste basique et en lui attribuant le simple droit de lecteur pour que le script ne modifie rien, mais le soucis se passe sur la lecture du contenu, rien ne se passe.

J'ai testé quelque chose en très basique et un peu brute.

Code :
1
2
3
4
#!/bin/bash
ls -R >liste.txt
chmod 444 liste.txt
read -r liste.txt
-R car j'ai parfois certains sous dossier mais ont les mêmes traitement que les fichiers racine.
Mon read ne retourne rien pour la suite.

J'ai cherché un peu avec xarg mais ne j'ai rien trouvé d'applicable pour lire le contenu et ensuite lancer un traitement du type " if = 1 (existe déja) move and increase sans créer de dossier if = 0 (n'existe pas) créer le dossier & move"
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 14h12   #2
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
Bonjour,

la commande interne read lit des données depuis l'entrée standard; pas depuis un fichier (pas toute seule : Comment lire/parcourir un fichier)
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 14h27   #3
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Donc oui après avoir lu le poste (merci pour le lien)

je dois partir sur une boucle avec while, le problème restant qui ne pourra pas faire avancer le projet est, y a t'il moyen de ne pas tenir compte des caractères spéciaux ou des numéros de la lecture. je pensais faire l'exception avec mais le soucis est que j'ai du mal à la construction "complexe" avec cette commande.

Une base plus propre:

Code :
1
2
3
4
5
6
7
8
#!/bin/bash
$repertoire=/sda06/*
$fichier="${repertoire}/liste.txt"
ls -R >$fichier
chmod 444 $fichier
while read Ligne
do echo "$Ligne"
done < $fichier
aerane est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 14h41   #4
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
qu'entends-tu exactement par «ne pas tenir compte des caractères spéciaux ou des numéros de la lecture»
les numéros, je vois bien; mais les «caractères spéciaux» pas forcément comme toi
tu peux nous montrer un avant/après, s'il te plaît.
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 15h04   #5
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Disons que la j'en ai pas 36 il s'agit de: - _ [ ] % j'ai dû faire le tour des plus utilisés dans les noms de fichiers.
Travaillant avec beaucoup de distributeur et client c'est à moi d'adapter le traitement et non de faire une normalisation des noms de fichiers plus tôt casse tête car tout le monde n'a pas la même façon de les traités avant la réception sur mes machines.

Je dois les exclure avec les numéros pour le classement ne répertoire portant le même nom.
Qu'il voit enfaîte le nom comme si c’était des espaces partout...

Gestion_de_stock ou gestion%de%stock resterai interpréter en Gestion de stock.

Ou alors faire un rename en remplaçant les caractère par des espaces...
Les fichiers sont après traités à partir de personnes ayant peu de connaissances informatique et mit à disposition de services sur des répertoires sous windows.

Il y a déjà une automatisation où, une fois le fichier rangé et au bon format, un script ftp les récupères simplement.

Ayant récupéré le poste il y a peu j'essai de faire une automatisation au lieu de tout faire à la main (et ca me prend une bonne matinée pour traiter 2 à 3 jours)
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 15h08   #6
jack-ft
Membre Expert
 
Inscription : avril 2008
Messages : 799
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 799
Points : 1 808
Points : 1 808
Citation:
Envoyé par aerane Voir le message
y a t'il moyen de ne pas tenir compte des caractères spéciaux ou des numéros de la lecture

Code :
1
2
3
4
5
6
7
8
#!/bin/bash
$repertoire=/sda06/*
$fichier="${repertoire}/liste.txt"
ls -R >$fichier
chmod 444 $fichier
while read Ligne
do echo "$Ligne"
done < $fichier
Quelles sont les spécifications?

Veux-tu dire (en pseudo-pseudo-code):
Code :
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
repertoire=/sda06/*
fichier="${repertoire}/liste.txt"
ls -R >$fichier
chmod 444 $fichier
while read Ligne
do echo "$Ligne"
  # copier le fichier dont le nom est décrit dans "$Ligne"
  #   dans un répertoire (à déterminer selon certains critères)
  #   en supprimant du nom original certains caractères (qui ne me plaisent pas... oops... qui peuvent poser problème)
done < $fichier
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 15h11   #7
jack-ft
Membre Expert
 
Inscription : avril 2008
Messages : 799
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 799
Points : 1 808
Points : 1 808
Citation:
Envoyé par aerane Voir le message
Ayant récupéré le poste il y a peu j'essai de faire une automatisation au lieu de tout faire à la main
ça semble être une bonne idée!

Citation:
(et ca me prend une bonne matinée pour traiter 2 à 3 jours)
Si tu pouvais nous montrer sur une dizaine de lignes ce que tu fais à la main, on verrait mieux ce qu'il te faut!
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 15h20   #8
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
alors j'essai de faire simple
sdb1 = arriver de tout les fichiers en vracs
fichier = tout type de nom et de format
nom différent = toto_test_[1] / toto%test%01 / toto_-_test_005 en exemple de nom
format = txt ou csv (cela importe peu c'est le nom qui joue)
sda6 = partition ou mettre à dispo les fichiers pour la récupération vers windows

Donc le matin je m'amuse à me rendre sur sdb1 trier et corriger le nom des fichiers en "toto test 01" pour aller les placer dans le bon répertoire sur sda6 sachant que le script de récupération ne prend en compte pas ceux avec un autre format que celui corriger...

Et en fonction des arrivés (tout les mois sda6 est sauvegardé et tout le contenu du repertoire de mise à dispo vidé) je dois recréer le dossier.

Pour info c'est une plateforme sous ubuntu.
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 15h28   #9
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
comment tu connais «le bon répertoire» ?

pourquoi des espaces (peu pratiques), et pas des soulignements ?
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 15h39   #10
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Je connais le bon répertoire par nom en faisant à la main. donc ca serai quelque chose d'un peu lourd à faire... avec un ou pour trouver le répertoire avec le même nom...Le nom se trouverai car un dossier n'a pas d'extention. c'est ca qui est bien hardu à faire.

sinon il faudrait définir avec un
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
repertoire=/sda06/*
fichier="${repertoire}/liste.txt"
ls -R >$fichier
chmod 444 $fichier
while read Ligne
do echo "$Ligne"
if exist  # copier le fichier dont le nom est décrit dans "$Ligne"
  #   dans un répertoire (à déterminer selon certains critères)
  #   en supprimant du nom original certains caractères (qui ne me plaisent pas... oops... qui peuvent poser problème)
 
fi
if not exist #mkdir #nom du fichier en guise de nom de répertoire) $repertoire
  #copier le fichier dont le nom est décrit dans "$Ligne"
  #   dans un répertoire (à déterminer selon certains critères)
  #   en supprimant du nom original certains caractères (qui ne me plaisent pas... oops... qui peuvent poser problème)
 
fi
done < $fichier
si le répertoire existe tout simplement à partir du nom du fichier dans la destination racine.

Pourquoi pas d'underscore (soulignement) ? Car les gens passant sur les fichiers sous ce format, pour eux ce n'est pas bien traiter...d'où un soucis même en le leur disant par voix officiel (mon prédécesseur a essayé...) et d'un autre le script de récupération a été modifier pour cela...Il ne récupère plus que ceux avec espace, et je n'y ai pas accès pour voir comment ils ont mit ca en place il est lancé d'une autre plate forme (celle de destination réel) avec un appel ssh
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 16h01   #11
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
pour l'exemple :
Code :
1
2
$ mkdir -p monDir/monSousDir{1..4}
$ touch monDir/monSousDir{1..4}/fi-c_h%ier123
avec find et bash , c'est très simple
Code :
1
2
3
4
5
6
$ shopt -s extglob
$ find monDir/ -type f -printf '%h|%f\n' | while IFS='|' read d f; do printf 'dir= %s; fic= %s\n' "$d" "${f//+([[:punct:]]|[0-9])/ }"; done
dir= monDir/monSousDir1; fic= fi c h ier 
dir= monDir/monSousDir4; fic= fi c h ier 
dir= monDir/monSousDir2; fic= fi c h ier 
dir= monDir/monSousDir3; fic= fi c h ier
dans la boucle while, tu peux alors tester l'existence de "$d" (dont on peut remplacer monDir par rien, à l'aide d'un simple remplacement des paramètres (c'est dans le man)).
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 16h14   #12
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Le problème du find avec l'exemple ci dessus est que la variable serai à répéter à partir de chaque ligne de la liste non ? Ayant une liste variable en nombre de ligne...j'ai un peu de difficulté à le voir sous script.

Après je peux voir a prendre la solution des underscore à la place des espaces et voir l'admin réseaux pour le script de récupération.

Et pour les gens ont leur dira simplement c'est le nouveau format et pas de négociation, c'est déjà assé hardu à trouver le moyen de faire pour moi
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 17h12   #13
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
Citation:
Le problème du find avec l'exemple ci dessus est que la variable serai à répéter à partir de chaque ligne de la liste non ?
quelle variable ?
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 17h20   #14
jack-ft
Membre Expert
 
Inscription : avril 2008
Messages : 799
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 799
Points : 1 808
Points : 1 808
Citation:
Envoyé par aerane Voir le message
alors j'essai de faire simple
sdb1 = arriver de tout les fichiers en vracs
fichier = tout type de nom et de format
nom différent = toto_test_[1] / toto%test%01 / toto_-_test_005 en exemple de nom
format = txt ou csv (cela importe peu c'est le nom qui joue)
sda6 = partition ou mettre à dispo les fichiers pour la récupération vers windows

Donc le matin je m'amuse à me rendre sur sdb1 trier et corriger le nom des fichiers en "toto test 01" pour aller les placer dans le bon répertoire sur sda6 sachant que le script de récupération ne prend en compte pas ceux avec un autre format que celui corriger...

Et en fonction des arrivés (tout les mois sda6 est sauvegardé et tout le contenu du repertoire de mise à dispo vidé) je dois recréer le dossier.

Pour info c'est une plateforme sous ubuntu.
C'est un peu plus clair...

Pour la correction des noms, j'aurais préféré que tu décrives ce que tu fais de la manière suivante:
Code :
1
2
3
4
5
cd /sdb1
mv 'toto_test_[1]' 'toto test 01'
mv 'toto%test%02' 'toto test 02'
mv 'toto_-_test_005' 'toto test 05'
etc.
je n'ai pas compris s'il y avait une gestion de sous-répertoires et laquelle.

Pour le transfert:
Code :
1
2
3
4
5
cd /sdb1
cp 'toto test 01' sda6/quel_repertoire?
cp 'toto test 02' sda6/quel_repertoire?
cp 'toto test 05' sda6/quel_repertoire?
etc.
Est-ce proche de ce que tu fais à la main?
Peux-tu corriger en gardant la même présentation?
Afin que nous puissions généraliser plus facilement, peux-tu rajouter quelques exemples?
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 17h30   #15
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Quand je parlais de variable je parlais pour chaque ligne du fichier comportant les noms en fait.

Le meilleur ordre serait de faire le changement de nom, refaire la liste et lancer la classification.
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 17h47   #16
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
on peut tout faire d'un coup, sans fichier temporaire (et surtout sans ls).

donc,
  • retrouver les fichiers avec find
  • formater la sortie de find pour distinguer le répertoire et le nom des fichiers
  • dans la boucle while
    • tester l'existence du répertoire, sinon le créer,
    • modifier le nom du fichier,
    • copier, ou déplacer le fichier en cours

il faut être précis.
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 18h00   #17
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Donc si je pars avec les morceaux fournis par vos soins et je vous en remercie grandement

je partirai sur une base du genre (j'ai juste mis dans l'ordre d’exécution)

Code :
1
2
3
4
5
6
7
8
9
10
11
$ shopt -s extglob
$ find monDir/ -type f -printf '%h|%f\n' | while IFS='|' read d f; do printf 'dir= %s; fic= %s\n' "$d" "${f//+([[:punct:]]|[0-9])/ }"; done
dir= monDir/monSousDir1; fic= fi c h ier 
dir= monDir/monSousDir4; fic= fi c h ier 
dir= monDir/monSousDir2; fic= fi c h ier 
dir= monDir/monSousDir3; fic= fi c h ier
 
cd /sdb1
cp 'toto test 01' sda6/quel_repertoire?
cp 'toto test 02' sda6/quel_repertoire?
cp 'toto test 05' sda6/quel_repertoire?
si je comprend bien la première partie, il recrée sa propre liste pour la recherche des noms de fichiers en excluant bien ce que je ne dois pas prendre en compte.

en gros je me trouve sur sdb1/CFT/reception que je transfert vers sda6/MCT/Reporting
Je peux pas réellement donner le nom réel des fichiers pour clause de confidentialité
aerane est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 18h20   #18
N_BaH
Modérateur
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 755
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 755
Points : 6 628
Points : 6 628
± le printf n'est là que pour montrer comment se déroule le remplacement de paramètre.

le cd n'est pas obligatoire
tout se fait dans la boucle while.
Code :
1
2
3
4
5
6
7
8
shopt -s extglob
src="/sda1/CFT"
find "$src" -type f -printf '%h|%f\n' | while IFS='|' read d f
do
   dest="/sda6/MCT/${d/$src\/}"
   test -d "$dest" || echo mkdir -p "$dest"
   echo cp "$d/$f" "/sda6/$dest/${f//+([[:punct:]]|[0-9])/ }"
done
si c'est bon, enlève les echo.

n'oublie pas de mettre en
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 18h37   #19
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
je teste ca au plus vite et reviens dire ce qu'il en est.

Un grand merci en tout cas pour l'aide la compréhension les réponses rapides et le temps que vous me libérez avec la solution rien que pour une seule semaine
aerane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 19h45   #20
aerane
Membre du Club
 
Homme irwin
Analyste d'exploitation
Inscription : janvier 2012
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme irwin

Informations professionnelles :
Activité : Analyste d'exploitation
Secteur : Finance

Informations forums :
Inscription : janvier 2012
Messages : 83
Points : 50
Points : 50
Bon, je viens de le tester à mon domicile en jouant sur un DD externe en guise d'avoir pas mal de fichier avec les mêmes caractères ou autre que au boulot. (ubuntu aussi)

Code :
1
2
3
4
5
6
7
8
9
 
shopt -s extglob
src="/media/1To/a_trier"
find "$src" -type f -printf '%h|%f\n' | while IFS='|' read d f
do
   dest="/media/1To/trier/${d/$src\/}"
   test -d "$dest" || echo mkdir -p "$dest"
   echo cp "$d/$f" "/media/1To/$dest/${f//+([[:punct:]]|[0-9])/ }"
done
j'ai en message retour:

Code :
1
2
3
aerane@aerane-GX723:/media/1To$ sh tri_test_v01.sh
tri_test_v01.sh: 1: tri_test_v01.sh: shopt: not found
tri_test_v01.sh: 5: tri_test_v01.sh: Bad substitution
aerane est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 01h26.


 
 
 
 
Partenaires

Hébergement Web