Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 sad  (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 tongue

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 tongue)

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)

tongue

#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.

Hors 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 :

Tawal a écrit :

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.

Hors 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 roll), 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.

Tawal a écrit :

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.

Hors 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.

Hors 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 smile


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 tongue) que j'ai adoptée.

kamaris a écrit :

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