find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort |uniq
Ce qui précède trouve tous les fichiers situés sous le répertoire en cours ( .
) qui sont des fichiers normaux ( -type f
) et ont f
quelque part dans leur nom ( -name '*f*'
). Ensuite, sed
supprime le nom du fichier, ne laissant que le nom du répertoire. Ensuite, la liste des répertoires est triée ( sort
) et les doublons supprimés ( uniq
).
La sed
commande consiste en un seul substitut. Il cherche des correspondances avec l'expression régulière /[^/]+$
et remplace tout ce qui correspond à rien. Le signe dollar signifie la fin de la ligne. [^/]+'
signifie un ou plusieurs caractères qui ne sont pas des barres obliques. Ainsi, /[^/]+$
signifie tous les caractères de la dernière barre oblique à la fin de la ligne. En d'autres termes, cela correspond au nom du fichier à la fin du chemin complet. Ainsi, la commande sed supprime le nom du fichier, laissant inchangé le nom du répertoire dans lequel se trouvait le fichier.
Des simplifications
Beaucoup de sort
commandes modernes supportent un -u
drapeau qui rend uniq
inutile. Pour GNU sed:
find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort -u
Et pour MacOS sed:
find . -type f -name '*f*' | sed -E 's|/[^/]+$||' |sort -u
De plus, si votre find
commande le prend en charge, il est possible d’ find
imprimer directement les noms de répertoire. Cela évite le besoin de sed
:
find . -type f -name '*f*' -printf '%h\n' | sort -u
Version plus robuste (nécessite des outils GNU)
Les versions ci-dessus seront confondues avec les noms de fichiers qui incluent des nouvelles lignes. Une solution plus robuste consiste à effectuer le tri sur les chaînes terminées par NUL:
find . -type f -name '*f*' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'
uniq
utile d’y ajouter des éléments en supprimant les lignes répétées qui sont déjà juxtaposées.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. Ou si vos outils sont un peu plus anciens, uniq peut ne pas avoir l'option -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u
-E
pour MacOS.Pourquoi ne pas essayer ceci:
la source
find
sont en réalité assez clairsemées - l'-printf
opérateur n'est pas spécifié. Cela ne fonctionne pas avec BSDfind
. Donc, pas "entièrement compatible POSIX". (Quoiquesort -u
soit dans POSIX .)Il existe essentiellement 2 méthodes que vous pouvez utiliser pour cela. L'un analysera la chaîne pendant que l'autre opèrera sur chaque fichier. L'analyse de la chaîne utilise un outil tel que
grep
,sed
ouawk
va évidemment être plus rapide, mais voici un exemple montrant les deux, ainsi que la manière dont vous pouvez "profiler" les 2 méthodes.Échantillon de données
Pour les exemples ci-dessous, nous utiliserons les données suivantes
Supprimer certains des
*f*
fichiers dedir1/*
:Approche n ° 1 - Analyser via des chaînes
Ici , nous allons utiliser les outils suivants,
find
,grep
etsort
.Approche n ° 2 - Analyser à l'aide de fichiers
Même chaîne d'outils qu'avant, sauf que cette fois, nous utiliserons la
dirname
place degrep
.Remarque: les exemples ci-dessus sont utilisés
head -5
pour limiter simplement la quantité de sortie que nous traitons pour ces exemples. Ils seraient normalement supprimés pour obtenir votre liste complète!Comparer les résultats
Nous pouvons utiliser
time
pour regarder les 2 approches.nom de répertoire
grep
Il est donc toujours préférable de manipuler les chaînes si possible.
Méthodes alternatives d'analyse de chaînes
grep & PCRE
sed
awk
la source
En voici un que je trouve utile:
la source
Cette réponse est basée sans vergogne sur slm answer. C'était une approche intéressante, mais qui présente une limitation si les noms de fichier et / ou de répertoire ont des caractères spéciaux (espace, demi-colonne, etc.). Une bonne habitude est à utiliser
find /somewhere -print0 | xargs -0 someprogam
.Échantillon de données
Pour les exemples ci-dessous, nous utiliserons les données suivantes
Supprimer certains des
*f*
fichiers dedir1/*/
:Approche n ° 1 - Analyser à l'aide de fichiers
Remarque : les exemples ci-dessus sont utilisés
head -5
pour limiter simplement la quantité de sortie que nous traitons pour ces exemples. Ils seraient normalement supprimés pour obtenir votre liste complète! remplacez également laecho
commande que vous souhaitez utiliser.la source
Avec
zsh
:la source