Comment lister des fichiers dont aucun lien symbolique n'existe?


10

J'ai un grand répertoire "myfiles" plein de documents divers et je ne souhaite pas modifier sa structure.

J'ai donc créé (plusieurs) autres répertoires pour chaque classe de documents. Par exemple, j'ai un répertoire "images" qui a des liens symboliques vers chacun .jpgou un .cr2fichier dans le répertoire "myfiles" ainsi que d'autres fichiers descriptifs pour chaque lien symbolique (avec le même nom de fichier) avec description et autres métadonnées. Les liens symboliques dans le répertoire / images peuvent avoir un nom différent du fichier lié d'origine.

J'essaie de trouver le moyen le plus simple de m'assurer que chaque fichier image du répertoire "myfiles" possède un lien symbolique vers le répertoire "images".

Voir un exemple de la structure des dossiers

/myfiles/a.doc
/myfiles/b.jpg
/myfiles/c.cr2
/myfiles/d.mov

devrait résulter

/images/b_800x600.jpg
/images/b_800x600.desc
/images/c_3820x5640.cr2
/images/c_3820x5640.cr2

Pas une réponse complète, mais vous pouvez enregistrer les résultats d'un find /myfiles -type fdans un fichier, puis utiliser find /images -type l -exec readlink {} \; | egrep myfilespour obtenir une liste de fichiers qui sont liés par des liens symboliques, /imagespuis parcourir les résultats en faisant un sedsur chacun pour supprimer les chemins d'accès dans le premier fichier que vous enregistrez car ils ont déjà avoir le lien symbolique et les fichiers restants sont les fichiers qui n'ont pas le lien symbolique.
Bratchley

2
Est-il possible pour vous d'utiliser des liens physiques à la place, vous pouvez donc utiliser le compteur de liens physiques pour voir si vous avez des liens? En utilisant, ls -lvous pouvez voir le nombre de liens physiques dans la deuxième colonne.
Lambert

Faites ce que dit @Lambert. rmces répertoires de liens symboliques et utiliser pax -rwl -s "\|.*regex|modifes_filename|" /path/to/myfiles/*.jpg /path/to/jpg_dirpar exemple pour obtenir des liens physiques avec des noms de fichiers modifiés par programme pour uniquement ceux qui correspondent à vos fichiers jpgs. Vous pouvez en tirer beaucoup plus que cela - comme le traitement par lots basé sur les temps de changement, etc.
mikeserv

Réponses:


6

Si je comprends mal la question, vous avez besoin de fichiers dans mes fichiers qui n'ont pas de liens symboliques dans les images:

#!/bin/bash

OIFS="$IFS"
IFS=$'\n'

files="$(find myfiles/ -type f -name '*.jpg' -or -name '*.cr2')"
for f in $files; do
    list="$(find -L images/ -xtype l -samefile "$f")"
    if [[ "$list" == "" ]]; then
        echo "$f does not have symlink."
    fi
done

IFS="$OIFS"

Il y a une mise en garde avec cette approche si vous avez un fichier a.jpg dans le répertoire myfiles / 1 et que vous avez un lien symbolique vers ce fichier dans le répertoire images / 3 ou simplement dans images / le fichier ne sera pas signalé avec un lien symbolique manquant.


Merci ! Oui, vous avez bien compris. Fermer mais pas tout à fait. Ma faute n'est pas la vôtre :-) L'exemple que j'ai donné montre un répertoire simpliste de mes fichiers. En réalité, les fichiers image sous mes fichiers peuvent se trouver dans n'importe quel niveau arbitraire de répertoires imbriqués.
Robert Alexander

J'ai modifié la réponse pour rechercher dans des fichiers entiers, mais vérifiez si c'est ce que vous désirez.
taliezin

PRESQUE là :-) Votre script hoquet quand les fichiers ont des espaces (et peut-être d'autres conneries comme des apostrophes simples "en eux ...
Robert Alexander

Je pense que maintenant ça devrait aller
taliezin

Votre dernière modification divise chaque f à l'apparition de chaque lettre n! :-) J'ai cnahgé la ligne IFS à IFS = puis une nouvelle ligne du clavier puis une autre ". Maintenant, le partage semble fonctionner mais j'obtiens une longue séquence de" missinglinks.sh: 11: missinglinks.sh: [[: not found "
Robert Alexander

3

Je suppose que les fichiers sous myfilesne sont pas des liens symboliques et qu'aucun des noms de fichiers ne contient de nouvelles lignes. (Mon approche peut toujours fonctionner si ces hypothèses sont violées mais cela devient plus compliqué.) Je suppose également que vous avez l' readlinkutilitaire commun et qu'il prend -fen charge la canonisation des chemins, ce qui est le cas sous Linux (GNU et BusyBox), mais pas par exemple sur OSX.

Créez une liste de fichiers et triez-la pour faire bonne mesure:

find /myfiles -type f -print | sort >all.list

Construisez une liste de cibles de liens symboliques, avec des chemins absolus.

find /images -type f -exec readlink -f {} \; | sort >linked.list

Répertoriez les fichiers qui ne sont pas liés:

comm -32 all.list linked.list

Si vous utilisez un shell qui prend en charge la substitution de processus, vous pouvez tout mettre dans une seule commande:

comm -23 <(find /myfiles -type f -print | sort) \
         <(find /images -type f -exec readlink -f {} \; | sort)

Si les liens sous /imagessont absolus, vous pouvez utiliser readlinksans l' -foption, qui est disponible sous * BSD et OSX.


J'étais sur le point de publier quelque chose comme votre commcommande, mais je ne le ferai pas maintenant que je vois que vous l'avez déjà fait. Cependant, la redirection depuis sortn'a aucun sens; alors les substitutions de processus ne produiront rien. En outre, vous pouvez ajouter de nombreux répertoires à côté /imagessi vous souhaitez rechercher des fichiers dans /myfileslesquels ils ne sont pas liés par des liens symboliques à partir d'un certain nombre de répertoires /images.
tripleee

1
Voir stackoverflow.com/questions/7665/… pour des alternatives àreadlink -f
tripleee

@tripleee J'ai oublié de supprimer la redirection lorsque j'ai créé la version de redirection de processus, merci. Oui, vous pouvez facilement ajouter d'autres répertoires ou faire d'autres variantes.
Gilles 'SO- arrête d'être méchant'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.