#1 Le 05/11/2022, à 13:51
- Tawal
[Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Hello,
Je sais que le titre n'est pas très clair.
Je m'explique :
J'ai un fichier contenant une liste de fichiers/dossiers (nommés par leur chemin absolu) et triée alphabétiquement.
J'aimerais enlever de cette liste tout fichier ou dossier dont un de ses dossiers parent est explicitement nommé dans la liste.
Par exemple, une liste fictive :
/Doss1/fich1
/Doss1/rep
/Doss1/rep/fich
/Doss2
/Doss2/rep2/fichX
Je voudrais en résultat cette nouvelle liste :
/Doss1/fich1
/Doss1/rep
/Doss2
J'ai déjà une solution utilisant awk, la voici :
awk 'NR==1{l="\0"}; {if ($0 ~ l){next}else{print}; l=$0}' liste > liste.tmp
mv liste.tmp liste
Mais cette solution m'oblige à passer par un fichier temporaire.
J'aimerais ne pas utiliser de fichier temporaire.
Avez-vous une idée ?
Merci.
Edit:
Je pensais aussi que sed pourrait le faire mais son option --in-place passe aussi par un fichier temporaire.
Du coup, j'ai développé une autre solution en bash cette fois-ci :
x=1
while read -r l
do
[[ $l =~ $x ]] && continue || Reste[$((i++))]="$l"
x="$l"
done < liste
(IFS=$'\n'; echo "${Reste[*]}") > liste
Mais bon, je trouve ça bof (edit2: même algorithme que la méthode awk)
Mais je me demande si le problème ne pourrait pas se résumer à :
Comment lire un fichier pour le ré-écrire sans passer par un fichier temporaire ?
Dernière modification par Tawal (Le 07/11/2022, à 12:31)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#2 Le 05/11/2022, à 13:58
- iznobe
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Bonjour , tu pourrais te baser sur un script ( je sais que c' est souvent ton point fort ) qu ' on avait creer a l' epoque avec geole pour changer le nom des fichiers , a un moment donné , il y avait dedans peut etre quelquechose qui pourrais te servir :
https://forum.ubuntu-fr.org/viewtopic.p … #p22519739
Dernière modification par iznobe (Le 05/11/2022, à 13:59)
retour COMPLET et utilisable de commande
MSI Z490A-pro , i7 10700 , 32 GB RAM .
Hors ligne
#3 Le 05/11/2022, à 14:26
- Tawal
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Merci de ta réponse.
Mais je n'y trouve pas mon bonheur.
(bon, j'ai lu le script en diagonale)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#4 Le 05/11/2022, à 14:39
- Tawal
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Re,
On peut aussi combiner la solution awk et bash :
mapfile -t Reste < <(awk 'NR==1{l="\0"}; {if ($0 ~ l){next}else{print}; l=$0}' liste)
(IFS=$'\n'; echo "${Reste[*]}") > liste
Voilà, j'ai épuisé mon sac
Edit:
Arff, je viens de m'en rendre compte : le
(IFS=$'\n'; echo "${Reste[*]}") > liste
ne tient pas si un nom de fichier a un espace.
Donc ma toute 1ère solution (awk + mv) est la plus solide (que j'ai )
Dernière modification par Tawal (Le 05/11/2022, à 14:53)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#5 Le 05/11/2022, à 15:21
- LeoMajor
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
salut,
une équivalence sed -i ?
awk -i inplace -v INPLACE_SUFFIX=.bak 'NR==1{l="\0"}; {if ($0 ~ l){next}else{print}; l=$0}' liste
Hors ligne
#6 Le 05/11/2022, à 15:51
- Compte supprimé
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Bonjour,
En python3:
from pathlib import PurePath
chemins = ['/Doss1/rep', '/Doss1/rep/fich', '/Doss2', '/Doss2/rep2/fichX']
for chemin in chemins:
p = PurePath(chemin)
if not str(p.parent) in chemins:
print(chemin)
#7 Le 05/11/2022, à 16:32
- Watael
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
personne ne vérifie que la "regex" est bien au début du chemin ?
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#8 Le 05/11/2022, à 16:51
- Compte supprimé
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Pourquoi vérifier puisqu’il est dit :
J'ai un fichier contenant une liste de fichiers/dossiers (nommés par leur chemin absolu)
#9 Le 05/11/2022, à 17:13
- Watael
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
parce que le fichier à traiter peut contenir
/Doss1/fich1
/Doss1/rep
/Doss2/Doss1/rep/fich
/Doss2/rep2/fichX
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#10 Le 05/11/2022, à 17:38
- Compte supprimé
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
ah oui dans le cas homonymes ... Je n'ai pas vraiment étudier les solutions apportées (trop d'effort ), la mienne gére cela.
La lib utilisée travaille vraiment sur le nom des chemins, elle ne joue pas avec le contenu d'une string...
Dernière modification par Compte supprimé (Le 05/11/2022, à 17:39)
#11 Le 05/11/2022, à 20:18
- kamaris
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
J'aimerais ne pas utiliser de fichier temporaire.
Tu ne peux pas lire et éditer un fichier en même temps. Tout mode d'édition in place passe par un fichier temporaire, d'une manière ou d'une autre.
Hors ligne
#12 Le 05/11/2022, à 21:27
- Watael
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
on peut imaginer stocker dans un tableau ce qui serait afficher, et écraser le fichier lu par la boucle quand elle est terminée :
#pseudo-code
tantQue lire ligne depuis /chemin/fichier
faire
tests $ligne ET tableau=$tableau+$ligne
finTantQue
afficher $tableau dans /chemin/fichier
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#13 Le 05/11/2022, à 22:14
- Tawal
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
@kamaris : Merci, au moins c'est clair.
@Watael : Tout à fait, c'est que je fais dans ma solution bash sauf que mon "afficher tableau dans liste" n'est pas correct.
Et bien vu pour la vérification de la regex au début. Mais dans mon cas précis, l'exemple que tu cites ne peut en aucun cas arriver.
Donc, au final, ma solution avec awk et mv n'est pas si mauvaise.
Sinon, sans fichier temporaire, une boucle pour lire et trier le fichier dans un tableau, puis une autre boucle pour afficher ce tableau dans le fichier (par écrasement).
Edit:
Une solution en bash :
x=1 # Caractère connu pour ne pas être dans le chemin du 1er fichier listé
while read -r l
do
[[ $l =~ $x ]] && continue || Reste[$((i++))]="$l"
x="$l"
done < liste
rm liste
for i in ${!Reste[@]}
do
echo "${Reste[$i]}" >> liste
done
Dernière modification par Tawal (Le 05/11/2022, à 22:29)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#14 Le 05/11/2022, à 22:31
- Watael
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
#!/bin/bash
...
[[... || Reste+=( "$l" )
...
#rm liste
printf '%s\n' "${Reste[@]}" >liste
Dernière modification par Watael (Le 05/11/2022, à 22:32)
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#15 Le 05/11/2022, à 22:52
- Tawal
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Merci pour ces précisions
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#16 Le 07/11/2022, à 12:30
- Tawal
Re : [Résolu] Épurer une liste de fichiers/dossier selon l'arborescence.
Re,
Je reviens pour exposer la solution finale (rhoo ) que j'ai adoptée.
Tu ne peux pas lire et éditer un fichier en même temps. Tout mode d'édition in place passe par un fichier temporaire, d'une manière ou d'une autre.
Donc, si on veut éditer "inplace", il faut stocker en mémoire le résultat et ré-écrire le fichier ensuite.
En bash, comme le soulignait Watael, il suffit de passer par un tableau.
Sauf que la solution pure bash est un peu lente sur de gros fichiers.
C'est pour cela que je garde la combinaison bash et awk :
mapfile -t Res < <(awk 'NR==1{l="\0"}; {if ($0 ~ l){next}else{print}; l=$0}' liste)
printf '%s\n' "${Res[@]}" >liste
Merci à vous de ces éclaircissements.
Je passe le sujet en résolu.
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne