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 10/02/2021, à 15:03

Hizoka

[Résolu] Script de vérification de l'existence de fichiers

Bonjour,

j'ai 2 fichiers :
- Fichiers.txt : il contient 461328 lignes, chaque ligne est l'adresse d'un fichier. (résultat d'un find)
- Liens.txt : il contient 477261 lignes, chaque ligne contient une adresse et d'autres infos.
Ces liens sont au format windows, je les ai changés en format linux avec pointage sur le montage.

Le but : Rechercher les liens morts.

Pour cela je boucle sur le fichier Liens.txt et je recherche les adresses dans le Fichier.txt.
Je les teste pour voir s'ils sont encore bons.
Si les liens n'existent plus je recherche les fichiers portant les même noms.
Je fais un grep dans Fichiers.txt plutôt qu'un find dans le point de montage car sinon c'est infernal niveau temps.

J'ai fait pas mal de tests mais cela prend beaucoup de temps, j'en suis à pas loin de 2h.

A votre avis y aurait-il moyen d'accélérer le process ?

J'en suis arrivé à ça :

while IFS='|' read -ra InfoFichier
do
    # Si on ne trouve pas le fichier, c'est que le lien est mort
    # Non prise en compte de la casse car windows et ses fichiers...
    # pas sur que test -e soit mieux car prise en charge de la casse par défaut et il faut accéder au point de montage...
    if ! grep -qi "${InfoFichier[1]}" Fichiers.txt
    then
        # je recherche les fichiers portant le même nom
        Propositions="$(grep -i "/${InfoFichier[1]##*/}" Fichiers.txt)"

        # Je fais quelques modifications pour avoir un format de lien windows et je rassemble les propositions
        Propositions="${Propositions//\/var\/www\/html\/share_dfs/S:/Espace_Collaboratifs}"
        Propositions="${Propositions//\/\\}"
        Propositions="${Propositions//$'\n'/ @@@ }"

        # Je renvoie le fichier et ses propositions (s'il y en a) dans un fichier 
        echo "${InfoFichier[0]}|${InfoFichier[2]}|${InfoFichier[3]}|${Propositions}"
    fi
done < Liens.txt > LiensMorts.txt

J'ai essayé de charger Fichiers.txt dans une liste mais la recherche dedans est plus lente.

J'ai tenté de remplacer les commandes des remplacements bash mais c'est un chouille plus lent...

J'ai fait plein de tests avec grep et sed mais les différences sont assez minimes.

Merci à vous smile

Dernière modification par Hizoka (Le 13/02/2021, à 10:42)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#2 Le 10/02/2021, à 15:15

beuguissime

Re : [Résolu] Script de vérification de l'existence de fichiers

Salut,
Tu pers sûrement beaucoup de temps à faire un grep dans les 460000 lignes, d'autant que le grep parcourt tout le fichier sauf si tu dis à grep de s'arrêter à la première correspondance (est-ce valable dans ton cas ?).

Exemple avec une répétition volontaire pour montrer que le grep s'arrête avant la fin du fichier

$ cat f.txt
fichier345
fichier234
fichier345
fichier126
$ grep fichier345 f.txt
fichier345
fichier345
$ grep -m1 fichier345 f.txt
fichier345

J'aurais plutôt fait une boucle sur un tableau à deux colonnes : le lien symbolique à vérifier et le fichier source correspondant. Comme ça, à chaque tour de boucle tu as toutes les infos nécessaires. J'ai l'impression que tu as tout ce qu'il faut pour faire ainsi.

Hors ligne

#3 Le 10/02/2021, à 16:11

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

La première chose que je ferais, c'est aussi de réduire le champ d'investigation des grep.
Seuls les liens morts t'intéressent, donc ta boucle bash devrait tourner sur un sous-ensemble de candidats aussi réduit que possible.
Or tu peux facilement éliminer les liens trivialement non-morts, avec quelque chose comme ça (à la lecture de ton post, c'est évidemment à ajuster et tester) :

join -t'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt)

Hors ligne

#4 Le 10/02/2021, à 19:25

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

@beuguissime :
Pas de gain de temps avec ou sans -m1, le -q doit avoir le même effet je pense.
Je n'ai pas compris ce que doit contenir le tableau.

@kamaris :
Excellente idée ! Merci beaucoup smile

Si je ne dis pas de bêtise, il me ressort les lignes de Liens.txt qui n'ont pu être jointes aux lignes de Fichiers.txt, c'est bien ça ?

La jointure étant sensible à la casse, il me faut laisser mon grep -qi du if.
Je me suis dis que je pouvais ajouter -i au join pour me passer de ce grep.

Mais là au lieu de me ressortir 4 500 lignes, le join m'en ressort 239 000.
Du coup, j'ai du rater un truc...

Et pour idée, je suis passé de 2h à .... 3min !!!

Karamis tu déchires !

Dernière modification par Hizoka (Le 10/02/2021, à 19:26)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#5 Le 10/02/2021, à 19:56

beuguissime

Re : [Résolu] Script de vérification de l'existence de fichiers

Ah oui, désolé, j'ai relu et ce qu'à quoi j'avais pensé ne correspond pas à ton cas. Oublie ma remarque (à part celle sur la probable perte de temps dans les grep wink).

Hors ligne

#6 Le 10/02/2021, à 21:11

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

Hizoka a écrit :

Si je ne dis pas de bêtise, il me ressort les lignes de Liens.txt qui n'ont pu être jointes aux lignes de Fichiers.txt, c'est bien ça ?

Oui, c'est bien ça (normalement).
Par contre c'est bizarre pour la sensibilité à la casse, comme ça ça devrait marcher :

join -it'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt)

Ce qui donnerait donc finalement

while IFS='|' read -ra InfoFichier
do
    # je recherche les fichiers portant le même nom
    Propositions="$(grep -i "/${InfoFichier[1]##*/}" Fichiers.txt)"

    # Je fais quelques modifications pour avoir un format de lien windows et je rassemble les propositions
    Propositions="${Propositions//\/var\/www\/html\/share_dfs/S:/Espace_Collaboratifs}"
    Propositions="${Propositions//\/\\}"
    Propositions="${Propositions//$'\n'/ @@@ }"

    # Je renvoie le fichier et ses propositions (s'il y en a) dans un fichier 
    echo "${InfoFichier[0]}|${InfoFichier[2]}|${InfoFichier[3]}|${Propositions}"
done < <(join -it'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt)) > LiensMorts.txt

Dernière modification par kamaris (Le 10/02/2021, à 21:16)

Hors ligne

#7 Le 10/02/2021, à 22:41

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

Bah ouais, c'est bien ce que j'avais essayé.

mais le join renvoie plus de ligne alors que ça devrait être l'inverse hmm

je reteste ça demain, je vous tiens au jus.

Encore merci Karamis


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#8 Le 10/02/2021, à 22:51

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

Bah non, c'est normal qu'il te renvoie plus de lignes si tu relaches une condition, ce qui est le cas en étant insensible à la casse au lieu de sensible (ou alors il y a quelque chose que j'ai mal compris).
Par contre, si 239 000 est bien finalement le bon nombre de lignes que join doit renvoyer, ça ne va diminuer le temps de calcul  que d'un facteur 2.
Il faudrait alors aussi optimiser le grep des propositions, ce qui est à priori moins évident.

Hors ligne

#9 Le 11/02/2021, à 07:02

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

d'abord, il faudrait "améliorer" l'intitulé du sujet.
ensuite, la démarche me chiffonne un peu, peut-être parce qu'il n'est pas dit que le système de fichier que tu vérifies n'est pas accessible, et que tu travailles sur une "image" contenue dans Fichiers.txt.
pourtant ce fichier est le "résultat d'un find".
alors, si le système de fichier est lisible, pourquoi ne pas simplement tester l'adresse retournée ?

edit: un tableau est-il indispensable ? le format du fichier est connu, et l'emplacement des données pertinentes aussi, donc simplement

tantQue lire ch1 ch2 reste; faire si test estUnFichier Transformer($ch2); alors ...; sinon ...; finSi; finTantQue

Dernière modification par Watael (Le 11/02/2021, à 07:06)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#10 Le 11/02/2021, à 11:55

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

@kamaris
Au contraire, dans ma logique, si les conditions sont moins exigeantes,
la commande fait plus de jointure et on a dit que la commande join ne ressort que les lignes qu'elle n'a pas réussi à joindre,
donc en toute logique le nombre de ligne qu'elle n'a pas réussi à joindre est moindre.

En mode test :

cat a
Fichier1
fichier2
fiChier3
Fichier4

cat b
fichier1
fichier2
fichier3
fichier4
fichier5

# Condition stricte, il ressort 4 lignes
join -v2 a b
fichier1
fichier3
fichier4
fichier5

# Condition large, il ressort 1 ligne
join -i -v2 a b
fichier5

Mais avec mes fichiers :

join -t'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt) | wc -l
4411

join -it'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt) | wc -l
238985

@Watael
Désolé pour le titre, j'ai zappé de le refaire.

ensuite, la démarche me chiffonne un peu, peut-être parce qu'il n'est pas dit que le système de fichier que tu vérifies n'est pas accessible, et que tu travailles sur une "image" contenue dans Fichiers.txt.

Bah, je ne l'ai pas dit parce que ce n'est pas le cas : Je fais un grep dans Fichiers.txt plutôt qu'un find dans le point de montage car sinon c'est infernal niveau temps.
Comme tu vas le voir, malgré tout, ça fait gagner du temps.

Je viens de faire un test sur 11 000 lignes.
Version de base : ~ 42s

Avec ta 1ere proposition :

while IFS='|' read -ra InfoFichier
do
    if [[ ! -e "${InfoFichier[1]}" ]]
    then
        if ! grep -qi "${InfoFichier[1]}" Fichiers.txt
        then
            Propositions="$(grep -i "/${InfoFichier[1]##*/}" Fichiers.txt)"
            Propositions="${Propositions//\/var\/www\/html\/share_dfs/S:/Espace_Collaboratifs}"
            Propositions="${Propositions//\/\\}"
            Propositions="${Propositions//$'\n'/ @@@ }"
            echo "${InfoFichier[0]}|${InfoFichier[2]}|${InfoFichier[3]}|${Propositions}"
        fi
    fi
done < Liens.txt > LiensMorts.txt

~ 12.5 sec
Sacré gain de temps en effet !

Tu propose de virer l'option -a du read ?

while IFS='|' read -r Id Lien Reste
do
    if [[ ! -e "${Lien}" ]]
    then
        if ! grep -qi "${Lien}" Fichiers.txt
        then
            Propositions="$(grep -i "/${Lien##*/}" Fichiers.txt)"
            Propositions="${Propositions//\/var\/www\/html\/share_dfs/S:/Espace_Collaboratifs}"
            Propositions="${Propositions//\/\\}"
            Propositions="${Propositions//$'\n'/ @@@ }"
            echo "${Id}|${Reste}|${Propositions}"
        fi
    fi
done < Liens.txt > LiensMorts.txt

~ 13sec
Ça semble un chouille plus long que l'autre test.


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#11 Le 11/02/2021, à 12:23

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

mais pourquoi deux grep ?
crée Propositions (pourquoi s ? grep peux remonter plusieurs occurrences ? alors ça devrait être un tableau, sur lequel il faudra itérer),
et teste si elle existe : si grep n'a rien retourné, elle sera vide (elle n'existera pas).

Dernière modification par Watael (Le 11/02/2021, à 12:23)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#12 Le 11/02/2021, à 12:48

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

Le 1er grep sert car avec windows, la casse n'est pas prise en compte.

ex avec un fichier .../test.JPG mais le lien .../test.jpg.
le test -e considère que le lien n'existe pas alors que windows s'en fout.
Avec le 1er grep, je considère que le lien existe et je m’arrête là.
Si je ne le fais pas, je vais me retrouver avec des liens OK (pour windows) qui me proposeront le nom exact en remplacement.
Je ne verrais pas en 1 clin d’œil si la proposition est le même emplacement ou s'il me propose un fichier ailleurs.
Ces lignes me feront perdre du temps dans leur traitement.

Oui le 2e grep peut remonter plusieurs lignes, je remplace les sauts de ligne par @@@.

Dernière modification par Hizoka (Le 11/02/2021, à 12:49)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#13 Le 11/02/2021, à 13:27

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

0.5 sec sur autant de lignes, je ne suis pas sûr que ce soit significatif.

deux grep sur le même fichier avec ± le même motif, c'est à mon avis un de trop.
est-ce qu'on ne pourrait pas en faire un seul awk ?

ah, et puis ces accolades, qui ne servent à rien, moi, ça me file le mal de mer. smile

PS:

if ! test -e "$lien"

les accolades doubles n'ont pas d'utilité ici.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#14 Le 11/02/2021, à 14:14

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

0.5 sec sur autant de lignes, je ne suis pas sûr que ce soit significatif.

Tout à fait, d'accord, c'est kiff kiff mais plus lisible.

Je ne maîtrise absolument pas awk.

ah, et puis ces accolades, qui ne servent à rien, moi, ça me file le mal de mer.

Je sais que tu ne les aimes pas, mais je trouve ça visuellement plus cohérent wink

les accolades doubles n'ont pas d'utilité ici.

Tu chipotes là lol
Surtout que test est plus lent que [[ ]].

time for ((x=1; x<100000; x++)); do test -e "popo"; done
real    0m0,480s

time for ((x=1; x<100000; x++)); do [[ -e "popo" ]]; done
real    0m0,372s

Ouais, sacrée différence tongue

En tout cas, merci à vous deux smile

Je ferai un résumé.

Dernière modification par Hizoka (Le 11/02/2021, à 14:16)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#15 Le 11/02/2021, à 14:33

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

tu vois à quel point ça me rend malade, j'ai écrit "accolades" en pensant "crochets".

tu sais que je vous reconnaîtrais tous (ceux qui mettent des trucs sans utilité) cet été, quand je verrai un gars en short avec un imperméable sur le bras.
et n'oubliez pas : si vous allez sur la station spatiale internationale, n'oubliez pas votre parachute. lol


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#16 Le 11/02/2021, à 14:51

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

Ouais...
tu peux porter des fringues crado ou mal assorties.
Ça fait le taf, tu n'auras pas plus froid qu'avec de jolis fringues mais c'est pas pour aussi agréable à regarder.

Ce ne sont que des pratiques personnelles.
Au même titre quand je fais du SQL je mets des AS facultatifs pour plus de lisibilité.

et niveau temps d’exécution, c'est la même chose...

Dernière modification par Hizoka (Le 11/02/2021, à 14:51)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#17 Le 11/02/2021, à 15:13

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

les AS, c'est pratique.
les accolades, c'est nASe.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#18 Le 12/02/2021, à 06:47

Watael

Re : [Résolu] Script de vérification de l'existence de fichiers

et pourquoi ne pas partir de l'existant (plus besoin de fichier temporaire Fichiers.txt, on utilise directement la sortie de find) pour chercher et supprimer les correspondances dans la liste des liens ?
tu aurais encore besoin de deux grep ?
il n'y aurait, au moins, plus qu'un seul fichier à lire, et pas avec le shell.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#19 Le 13/02/2021, à 01:27

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

Hizoka a écrit :

@kamaris
Au contraire, dans ma logique, si les conditions sont moins exigeantes,
la commande fait plus de jointure et on a dit que la commande join ne ressort que les lignes qu'elle n'a pas réussi à joindre,
donc en toute logique le nombre de ligne qu'elle n'a pas réussi à joindre est moindre.

Bien sûr, tu as raison, j'ai oublié une négation dans l'histoire.
Est-ce que le problème ne viendrait pas de sort qui, lui, n'est pas mis insensible à la casse ?

join -it'|' -11 -22 -v2 <(sort -f Fichiers.txt) <(sort -ft'|' -k2 Liens.txt)

Hors ligne

#20 Le 13/02/2021, à 10:42

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

@Kamaris
Snif, pas de changement sad
Même nombre de ligne renvoyé avec ou sans -f de sort.
Franchement je ne pige pas...

J'aurais bien aimé y arriver mais là, je ne vois pas la cause du problème...

Du coup, je vais m’arrêter là, un ÉNORME merci pour votre aide, au final voici mon code :

while IFS='|' read -r Fichier InfoFichier
do    
    # Si on ne trouve pas le fichier, c'est que le lien est mort, on test sans prise en compte de la casse car pas réussi à le faire directement avec join
    if ! grep -qi "${Fichier}" FichiersAsdia.txt
    then
        # Recherche des emplacements de fichiers portant le même nom
        Propositions="$(grep -i "/${Fichier##*/}" Fichiers.txt)"
   
        # Transforme l'adresse au format windows
        Propositions="${Propositions//\/var\/www\/html\/share_dfs/S:/Espace_Collaboratifs}"
        Propositions="${Propositions//\//\\}"
        Propositions="${Propositions//$'\n'/ @@@ }"

        # Remplissage du fichier de liens morts
        echo "${InfoFichier}|${Propositions}"
    fi
done < <(join -t'|' -11 -22 -v2 <(sort Fichiers.txt) <(sort -t'|' -k2 Liens.txt)) > LiensMorts.txt

Au final, je suis passé de 2h à ~ 3min smile

Vraiment merci !


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#21 Le 13/02/2021, à 11:30

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

C'est bizarre en effet.
Peut-être essayer avec --check-order histoire d'être sûr qu'il n'y a pas de problème de ce côté là (une option de sort à ajuster ?).

Hors ligne

#22 Le 13/02/2021, à 17:35

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

Voilà :

join -t'|' -11 -22 -v2 --check-order <(sort Fichiers.txt) <(sort -t'|' -k1 Liens.txt)
join: /dev/fd/62:2 : n'est pas trié : 100001|/var/www/html/share_dfs/17_XXX/Z_TRACES APNEE/2018/XXX.pdf|S:\Espace_Collaboratifs\XXX\Z_TRACES APNEE\2018\XXX.pdf|2018-12-18 09:45:40

join -it'|' -11 -22 -v2 --check-order <(sort Fichiers.txt) <(sort -t'|' -k1 Liens.txt)
join: /dev/fd/63:76: n'est pas trié: /var/www/html/share_dfs/XXX/ADMINISTRATIF/Certificat dedouanement patient/Certificat dédouanement pompe M.XXX.jpg

join -it'|' -11 -22 -v2 --check-order <(sort -f Fichiers.txt) <(sort -ft'|' -k1 Liens.txt)
join: /dev/fd/63:76: n'est pas trié: /var/www/html/share_dfs/XXX/ADMINISTRATIF/Certificat dedouanement patient/Certificat dédouanement pompe M. XXX.jpg

KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#23 Le 15/02/2021, à 19:08

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

Attention : tu tries Liens.txt sur le champ 1, alors qu'il faudrait le trier sur le champ 2.
Selon ton post initial, confirmé par le retour que tu donnes là, j'avais mis -k2 plus haut.

Hors ligne

#24 Le 15/02/2021, à 19:20

Hizoka

Re : [Résolu] Script de vérification de l'existence de fichiers

Désolé, c'est une erreur de copier coller, c'est bien -k2.

Mais il indique bien quelques erreur disant que ce n'est pas trié alors que ça l'est...


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#25 Le 18/02/2021, à 01:44

kamaris

Re : [Résolu] Script de vérification de l'existence de fichiers

Faut croire que ça n'est pas trié comme il faut, en tout cas il y a fort à parier que l'incohérence au niveau de l'insensibilité à la casse vienne de là.
Il faudrait isoler un échantillon des données qui bugue et essayer de voir pourquoi, parce que le problème, c'est que tant que ça n'a pas été corrigé, tu ne peux pas vraiment avoir confiance dans ce que te renvoie join.

Hors ligne