Sous bash, j'ai 2 fichiers texte contenant des noms. Le 1er avec des noms de fichiers, le 2eme avec les nouveaux noms que ces fichiers doivent avoir. exemple fic1.txt
23654.jpg
hello world.doc
ok, it's done.docx
...
fic2.txt
2018.jpg
old.doc
...
Donc, j'aimerais faire un petit mv et renommer mes fichiers en lot. Le problème c'est qu'un avec un seul argument une boucle "while read line" irait. Mais la commande mv à besoin de 2 arguments (l'ancien et le nouveau nom du fichier) et je ne peux pas faire 2 boucles en même temps...
Vu que j'ai des noms de fichiers avec des espaces des , ` et autre je me retrouve avec une erreur
mv: la cible 'Brass.jpg' n'est pas un répertoire
Sans espace ou autre cette commande marche.
Donc, comment m'y prendre ? Pour résumer, je voudrais lire ligne par ligne chacun de mes 2 fichiers pour me servir des sorties dans une autre commande.
Si tu ne sais pas faire tu as trois choix non-exclusifs:
Lire la doc: pas si simple surtout quand on ne sait pas où chercher.
Chercher sur ton moteur de recherche préféré: tu ne trouveras peut-être pas la solution exacte à ton problème.
Écrire un algo pour contourner le problème: donne rarement la solution la plus simple et performante quand on débute.
Tu ne sais pas lire deux fichiers dans la même boucle. Et c'est pas forcément évident de trouver comment faire depuis la doc, je l'avoue. Et un tuto comme celui d'OC ne contient pas tous les éléments pour le deviner.
Tu sais fusionner tes deux fichiers en un seul grâce à une recherche google. C'est un bon début. La seule chose qui te manque est de distinguer à quel fichier chaque partie de ligne fait référence. Mais si tu n'y arrives pas, c'est surtout parce que tu n'as pas essayé de comprendre comment paste fonctionne.
Lire une doc simple, clair et minimaliste comme le man du bash et écrit dans un bon français, pour tout comprendre, c'est clairement d'un certain niveau.
Mais si, je suis pas une super feignasse non plus, j'ai essayer et faut bien avouer que le man pour paste et hyper court. Il n'empêche que j'ai pas compris.
Sinon pour ceux que ça intéresse si vous tombé sur ce topic, voici une solution:
while read -r lineFic1 <&3; do read -r lineFic2 <&4; vm "$lineFic1" "$lineFic2"; done 3<fic1.txt 4<fic2.txt
Adapté à ce que tu savais déjà faire (assigner une valeur à une variable et lire un fichier ligne par ligne dans une boucle), et le tour était joué, c'était presque évident avec un algo écrit en langage naturel:
1. joindre fichier1 et fichier2 ligne par ligne dans fichier3
2. Tant que «lecture fichier3» faire:
a. assigner 1ère partie ligne à variable1
b. assigner 2ème partie ligne à variable2
c. renommer fichier:variable1 par fichier:varibable2
Fin Tant que
Fin
« un problème clairement exposé est à moitié résolu. »
Ce n'était pas la solution la plus élégante, mais au moins, ça avait le mérite que tu comprennais de A à Z ce que tu faisais. Et de pouvoir facilement reprendre et adapter ce script si besoin plus tard.
Le but était de joindre les 2 fichiers pour s'en servir dans la commande mv car je ne savais pas passer 2 arguments à la fois dans une commande à partir de plusieurs fichiers, donc je voulais tout regrouper dans un seul.
Sans que les noms de fichier contenant des espaces, guillemet, virgule etc ne viennent faire planter la chose aussi.
La boucle while read qu'on m'a proposé marche très bien du coup et y'a même pas besoin de fusionner les 2 fichiers du coup.
Le résultat est le même mais la manière est différente. Dans ta liste de nom de fichier, il n'y avait pas de TABs? Il n'y avait pas tout les caractères possibles? Avec le bon délimiteur, tu pouvais séparer le contenu dans ta boucle.
Ton raisonnement était bon, tu ne savais lire qu'un fichier dans une boucle, alors tu as trouvé le moyen de joindre tes deux fichiers en un seul. Il te manquait juste le moyen de les séparer après. Mais tu savais le faire en fait. C'est ta méthode qui t'en as empêché:
AD4 a écrit:
Je voulais faire une sorte de
mv `cat fic1.txt` `cat fic2.txt`
Tu réfléchis directement en Bash. Reprendre l'algo en langage naturel puis traduire en Bash, t'aurais permit d'apercevoir la solution:
paste fichier1 fichier2 > fichier3 # 1. Choisir un délimiteur différent de TAB si besoin.
while read line; do # 2.
nom_fichier1=$(echo "$line" | cut -f1) # a. Utiliser le même délimiteur qu'avec paste.
nom_fichier2=$(echo "$line" | cut -f2) # b.
mv "$nom_fichier1" "$nom_fichier2" # c.
done < fichier3 # FIN Tant que
exit # FIN
Il ne faut pas hésiter à découper le problème. On aurait très bien pu faire a,b,c en une seule ligne, Mais ce serait moins clair.
La solution en utilisant le file descriptor 3 est plus directe. Mais si le fonctionnement d'un pipe ne te semble pas encore complètement clair. La solution avec le file descriptor 3 l'est encore moins. Alors qu'avec paste, je suis sûr que tu comprends parfaitement et en plus, tu l'as quasiment trouvé seul! Et c'est aussi important que le résultat.
Je trouve que le tuto d'OC ne permet pas d’appréhender pleinement les flux, les redirections et plus globalement les descripteurs de fichier (file descriptor). En français, je sais pas s'il existe de bon tuto pour . En anglais, je connais celui-ci: ici et là qui je trouve explique bien et avec des schémas.
Je regarderai les liens US que tu as mis, comme je me sert rarement de bash c'est sur que j'ai un niveau ras les pâquerettes mais je suis pas contre l’amélioré
passer des arguments dans mv à partir de 2 fichier
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique