web-dev-qa-db-fra.com

Supprimer tous les liens symboliques rompus avec une ligne?

Pour un dossier donné, comment puis-je supprimer tous les liens rompus qu'il contient?

J'ai trouvé cette réponse qui montre comment supprimer un lien cassé, mais je ne peux pas le rassembler en une seule ligne. Y a-t-il une doublure pour cela?

Une symbolique brisée est un lien qui pointe vers un fichier/dossier qui n'existe plus.

50
fotanus

Voici une manière POSIX de supprimer tous les liens symboliques rompus dans le répertoire courant, sans récursivité. Cela fonctionne en disant à find de parcourir les liens symboliques (-L), Mais en arrêtant (-Prune) À chaque répertoire ou lien symbolique vers tel.

find -L . -name . -o -type d -Prune -o -type l -exec rm {} +

Vous pouvez également utiliser une boucle Shell. Le test -L Correspond aux liens symboliques et -e Correspond aux fichiers existants (à l'exclusion des liens symboliques rompus).

for x in * .[!.]* ..?*; do if [ -L "$x" ] && ! [ -e "$x" ]; then rm -- "$x"; fi; done

Si vous voulez récursivement dans des sous-répertoires, cette technique ne fonctionne pas. Avec GNU find (comme on le trouve sur Linux non intégré et Cygwin), vous pouvez utiliser le prédicat -xtype Pour détecter les liens symboliques rompus (-xtype Utilise le type de la cible pour les liens symboliques et signale l pour les liens rompus).

find -xtype l -delete

POSIX, vous devez combiner deux outils. Vous pouvez utiliser find -type l -exec … Pour appeler une commande sur chaque lien symbolique et [ -e "$x" ] Pour tester si ce lien n'est pas rompu.

find . -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} +

La solution la plus simple consiste à utiliser zsh. Pour supprimer tous les liens symboliques rompus dans le répertoire actuel:

rm -- *(-@D)

Les caractères entre parenthèses sont qualificatifs globaux : - Pour déréférencer les liens symboliques, @ Pour correspondre uniquement aux liens symboliques (la combinaison -@ Signifie uniquement les liens symboliques rompus), et D pour faire correspondre les fichiers de points. Pour rentrer dans les sous-répertoires, faites cela rm -- **/*(-@D).

92
Gilles

Réponse simple basée sur la réponse que vous avez liée (pour un répertoire donné, $DIR):

find -L $DIR -maxdepth 1 -type l -delete
19
sanmiguel

De man find EXEMPLES:

find -L /usr/ports/packages -type l -exec rm -- {} +

Supprimer tous les liens symboliques rompus dans /usr/ports/packages.

6
Mr. Kennedy

Pour MAC , effectuez un essai à sec comme suit: -

DIR=<some path>
find -L $DIR -maxdepth 1 -type l -print

Maintenant, vous pouvez tailler les anciens liens symboliques comme suit: -

for f in `find -L $DIR -maxdepth 1 -type l`; do unlink $f; done
6
saurabheights

Réponse basée sur la réponse acceptée à la question question "Comment trouver des liens symboliques cassés" :

find . -type l -! -exec test -e {} \; -print | xargs rm
5
rayphi

Le paquet symlinks est préinstallé sur de nombreuses distributions (y compris Ubuntu 16.04 et Fedora 25) et possède des fonctionnalités vraiment utiles, dont l'une fait exactement ce que vous recherchez:

symlinks -d ./
3
SamWN

Vous pouvez utiliser readlink pour déterminer si un lien symbolique est cassé ou non.

Les éléments suivants répertorieraient tous les liens symboliques rompus dans un répertoire (et sous-répertoires) donné:

find . -type l -exec sh -c 'readlink -f "{}" 1>/dev/null || echo "{}"' -- "{}" \;

Remplacez echo par rm pour vous débarrasser des cassés!

(J'ai redirigé la sortie de readlink vers /dev/null afin d'éviter toute confusion; il listerait la cible des liens symboliques.)

2
devnull

Vous pouvez essayer d'utiliser rmlint .

Tout d'abord, changez de répertoire pour le dossier qui contient des liens symboliques rompus, puis exécutez les commandes suivantes pour trouver de mauvais liens symboliques pointant nulle part :

rmlint --types="badlinks"

rmlint créera un script bash rmlint.sh dans votre répertoire actuel et imprimez une liste des mauvais liens symboliques dans votre terminal. Pour supprimer tous les mauvais liens symboliques de votre répertoire actuel, vous pouvez exécuter

./rmlint.sh

Pas exactement un liner, mais il est très facile à utiliser.

0
Erdos Yi