Cela ne semble pas possible sans modification de la sortie, mais voici une alternative simple :
find source/ -type f
Ou (spécifique à GNU find), pour n'obtenir que les fichiers à la profondeur de votre question :
find source/ -type f -mindepth 2 -maxdepth 2
(ou si vous voulez des répertoires comme ls
vous donne, supprimez -type f
)
Vous pouvez simplement vous en tenir à ls si vous ajoutez des psychédéliques (ls -d
):
# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*
A/file B/file C/file
Vous pourriez être intéressé par "le find
du pauvre ” :
shopt -s globstar
shopt -s
s ets la ou les options shell nommées. Le globstar
l'option est définie comme suit dans bash(1) :
S'il est défini, le modèle
**
utilisé dans un contexte d'extension de nom de fichier/chemin d'accès correspondra à un fichier [sic] etzéro ou plusieurs répertoires et sous-répertoires. Si le motif est suivi d'un/
, seuls les répertoires et sous-répertoires correspondent.
Donc, après avoir fait shopt -s globstar
, l'une des commandes suivantes :
ls -d1 -- source/** # The character after the ‘d’ is the digit one. ls -d -- source/** | cat # i.e., it will write that into a pipe to any command. printf "%s\n" source/**
produira la sortie :
source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png
Malheureusement, cela inclut également les noms de répertoire. Cela pourrait vous aider un peu savoir que
printf "%s\n" source/**/
produira la sortie :
source/
source/fonts
source/images
c'est-à-dire seulement les noms des répertoires. Vous pouvez rediriger la sortie de l'un des premiers ensembles de commandes vers un fichier, rediriger la sortie de ce qui précède vers un deuxième fichier, puis utiliser comm
, diff
, ou quelque chose de similaire, pour soustraire le deuxième fichier du premier, ne laissant que les fichiers simples (non-répertoires). Mais ne faites pas ça.
Une autre approche (ce n'est pas beaucoup mieux) est
ls -d --file-type -- source/** | grep -v '/$'
Le --file-type
l'option indique ls
pour afficher un /
à la fin de chaque nom de répertoire (et d'autres caractères à la fin d'autres types de fichiers (spéciaux)), comme ceci :
source// # Added an extra one source/fonts/ # Added one source/fonts/fontello source/images/ # Added one source/images/bg1.png source/images/eng.png source/images/fra.png
puis le grep -v '/$'
supprime les lignes qui se terminent par /
;c'est-à-dire les noms des répertoires. Malheureusement, le --file-type
L'option n'est pas spécifiée par POSIX. Si votre version de ls
ne le supporte pas, utilisez -F
. C'est comme --file-type
sauf qu'il affiche aussi un *
à la fin des noms des fichiers exécutables, ce que certaines personnes trouvent ennuyeux. Vous pouvez les éliminer avec sed
:
ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'
Si vous voulez faire quelque chose avec tous les fichiers (et uniquement les fichiers), vous pouvez le faire
for f in source/** do if [ -f "$f" ] then Insert commands to be applied to plain files here. fi done
Remarques :
- Quand
ls
sort vers un terminal, et ce n'est pas en-l
(l ong), il écrit plusieurs noms par ligne (sauf si les noms sont très longs). Vous pouvez le forcer à écrire un nom par ligne en spécifiant-1
(un), ou en redirigeant la sortie vers un fichier ou un tube. - Vous n'avez probablement pas vraiment besoin du
--
dans lels
commandespuisque vous répertoriez un répertoire dont vous avez créé le contenu. Vous devez l'utiliser lors de l'inscription de*
dans un répertoire inconnu, comme protection contre les noms de fichiers commençant par-
. - N'essayez pas d'analyser la sortie de
ls
. - Le
globstar
L'option shell semble ne pas être définie par POSIX. (En fait, je ne suis pas sûr que POSIX reconnaisse tout options du shell.) Bien que cela semble être unbash
isme, méfiez-vous — il se peut qu'il ne soit pas présent dans toutes les versions de bash. -
Si
fonts
ouimages
a des sous-répertoires,**
les listera tous, récursivement, tout en bas. Un moyen (quelque peu confus et peu fiable) de limiter la profondeur estls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
qui supprime les lignes contenant trois ou plus
/
caractères.