«Find» sortie relative au répertoire


34

J'aimerais utiliser findpour lister tous les fichiers et répertoires de manière récursive dans une racine donnée pour une cpioopération. Cependant, je ne veux pas que le répertoire racine lui-même apparaisse dans les chemins. Par exemple, je reçois actuellement:

$ find diskimg
diskimg
diskimg/file1
diskimg/dir1
diskimg/dir1/file2

Mais j'aimerais avoir

file1
dir1
dir1/file2

(notez que la racine ne figure pas non plus dans la sortie souhaitée, mais c'est facile à éliminer tail).

Je suis sous OS X et je préfère ne pas installer d'outils supplémentaires (par exemple, GNU find) si possible, car j'aimerais partager le script que j'écris avec d'autres utilisateurs d'OS X.

Je suis conscient que cela peut être fait avec cutpour couper la liste racine, mais cela semble être une solution sous-optimale. Y a-t-il une meilleure solution disponible?


find diskimg/* | cut -d '/' -f2-
nik.shornikov

Réponses:


18

Si ce que vous essayez de faire n’est pas trop complexe, vous pouvez le faire avec sed:

find diskimg | sed -n 's|^diskimg/||p'

Ou cut:

find diskimg | cut -sd / -f 2-

vous pouvez choisir (presque) n'importe quel séparateur pour la commande, donc: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(remarque, j'ai ajouté aussi '-e', et une ^bonne pratique (pas nécessaire ici, car vous êtes sûr que toutes les lignes auront cette ... mais toujours une bonne pratique , et enregistre des cpu;))
Olivier Dulac

une autre manière sans grep: find diskimg | sed -e 's|^diskimg/*||' (le '/ *' correspondra à n’importe quel nombre de '/', même 0)
Olivier Dulac

Cette cutcommande est plus propre que celle que j'ai utilisée; Je l'aime. (La sedsolution est bien aussi, mais la répétition de diskimg/est un peu regrettable).
nneonneo

29

cd dans le répertoire en premier:

cd diskimg && find . 

Une fois terminé, vous serez de retour dans votre répertoire racine.

Vos fichiers seront précédés de ./ dans ce cas; le seul moyen que je vois autour de moi serait d'utiliser cut:

{ cd diskimg && find .; } | tail -n +2 | cut -c 3-

Utilisez un sous-shell pour éviter de changer le répertoire en cours de votre shell (cela n'est pas nécessaire si vous redirigez la sortie car le côté gauche d'un tuyau est déjà exécuté dans un sous-shell).

(cd diskimg && find .)

5
d'être de retour dans le répertoire d' origine à la fin: ajouter entre parenthèses: (cd diskimg && find . ; ). Ainsi, l'opération cd diskimg && find .est effectuée dans un sous-shell: lorsque ce sous-shell se ferme, vous revenez à votre propre shell, quel que soit votre répertoire.
Olivier Dulac

1
find *est une autre façon de contourner le préfixe inutile
nik.shornikov

23

Une autre solution, plus complexe mais utilisant uniquement la méthode find de mon autre réponse:

find diskimg -mindepth 1 -printf '%P\n'

Pas toutes les versions de findsupport printf.
Jordanie

1
Sûrement; Mon OSX ne semble pas. En partie pourquoi j'ai proposé une autre solution.
Stephan

2
@Stephan - la prochaine fois, vous pourrez simplement combiner ces types de réponses en une seule. Pas besoin de faire plusieurs réponses pour des écarts tels que celui-ci.
slm

2
Seul GNU est findcompatible -printf, alors que de nombreux BSD findont copié certaines des fonctionnalités de GNU find, aucune n’a -printfencore été copiée (autant que je sache).
Stéphane Chazelas

le %Ppour le chemin relatif était ce dont j'avais besoin.
Fl0v0

4

Utilisez l' realpathutilitaire:

find diskimg -exec realpath --relative-to diskimg {} \;

Neat - merci de me montrer --relative-to.
Nneonneo
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.