Recherche de sous-répertoires dans tous les répertoires du même nom

8

Je veux exécuter une commande pour:

  1. Recherchez tous les répertoires nommés " inc" sous un dossier " X".
  2. Liste tous les sous-répertoires sous chaque " X/.../inc/".
  3. Redirigez la sortie vers un fichier nommé " list"

J'ai essayé diverses combinaisons de la commande ci-dessous, sans succès:

$ find X/ -name "inc" -print | xargs find {} -type d > list
find: path must precede expression

Comment puis-je faire ceci?

iammilind
la source

Réponses:

13

find peut le faire tout seul:

find X -path '*/inc/*' -type d > list

Lisez la -pathpartie de man findpour plus d'informations.

Comme je l'ai mentionné rapidement dans un commentaire: si vous stockez la ligne des répertoires séparée dans un fichier texte, les noms de répertoires contenant des sauts de ligne ne seront pas représentés sans ambiguïté. Si vous êtes certain que les répertoires ne contiennent pas de retours à la ligne, c'est OK. Juste une remarque générale.

Daniel Andersson
la source
oui. j'ai donné la même réponse ici
Prince John Wesley
Ou trouvez X -name 'inc' -type d> list
MaQleod
@MaQleod: Non, ce n'est pas la question.
Daniel Andersson
4

Voici une doublure pratique:

find X -type d -name "inc" -exec sh -c 'find {} -type d' \; > list

Il s'exécute findsur chacun des premiers findrésultats. L' execoption peut également prendre une commande shell minimale, dans laquelle - comme je l'ai dit - {}est remplacée par chaque répertoire du premier find.

Le second find"listera tous les sous-répertoires" des premiers résultats, y compris le incrépertoire. Si vous ne voulez pas cela lui-même dans la sortie, laissez le deuxième dossier de sortie find au moins de profondeur 1.

find X -type d -name "inc" -exec sh -c 'find {} -mindepth 1 -type d' \; > list

Nous allons ensuite simplement rediriger la commande stdoutvers list.

slhck
la source
une variation de cette réponse m'a été utile, car je ne voulais que des sous-répertoires de profondeur 1 de la correspondance d'origine find path -name inc -type d -exec sh -c 'find {} -mindepth 1 -maxdepth 1 -type d' \;
Core
1

D'accord, j'ai trouvé la réponse pour simuler cette découverte imbriquée:

find X/ -type d | grep "/inc/" > list
iammilind
la source
Bien, ça marchera aussi! Cependant, dans les shells Unix / Linux, la réponse n'existe vraiment pas . C'est un mélange de préférences personnelles et de ce qui est facile à suivre.
Vishal Kotcherlakota
Pour prendre soin des noms de fichiers non conventionnels (mais existants) avec, par exemple, des sauts de ligne: find X/ -type d -print0 | awk 'BEGIN{RS="\0"}/\/inc\//' > list( grep -zdélimite également le caractère nul, mais sa sortie semble également être séparée par des valeurs nulles, alors il faudrait alors le passer par exemple xargs -0L1 echopour l'obtenir ligne par ligne ). Dans ce cas, étant donné que vous enregistrez la liste dans un fichier avec chaque entrée séparée par un retour à la ligne, les retours à la ligne dans les noms de fichiers seront toujours représentés de manière ambiguë. Vous n'avez peut-être même pas besoin du fichier intermédiaire, selon ce que vous voulez faire avec la liste.
Daniel Andersson
1

Essaye ça:

   find path-of-x -path '*/inc/*' -type d > list
Prince John Wesley
la source
Je n'ai pas de machine Linux pour le tester maintenant ...
Prince John Wesley
Ça ne marche pas. Mais merci de me suggérer "\inc\":)
iammilind
@iammilind: essayez avec le -pathdrapeau
Prince John Wesley