Comment récursive de la liste des sous-répertoires dans Bash sans l'aide de “trouver” ou “ls” commandes?
Je sais que vous pouvez utiliser le find
commande pour ce travail simple, mais j'ai eu une cession de ne pas utiliser find
ou ls
et de faire le travail. Comment puis-je le faire?
Ce que vous êtes censé utiliser pour ce faire? Votre propre script de shell, un programme en C, Java...? Si vous laissez-nous savoir ce que vous , l'utilisation, l'aide devrait être plus à l'aise 🙂
Vous pourriez être en mesure d'utiliser
Vous pourriez être en mesure d'utiliser
echo *
ou de variations sur que pour émuler ls
.OriginalL'auteur Raghubansh Mani | 2010-01-28
Vous devez vous connecter pour publier un commentaire.
vous pouvez le faire avec juste la coque
OU si vous avez bash 4.0
Ceci ne fonctionnera pas si le répertoire est vide, c'est à dire imprimer
dir: bla/*
depuisbla/*
est vu comme un littéral comme il n'a pas de descendants. Vous pouvez soit utiliserpushd/popd
, ou ajouterif [[ "$1/*" = "$i" ]]; then continue; fi
que la première ligne, aprèsdo
.Cela pourrait également être fixe (à ne pas émettre de
bla/*
) par l'utilisation deshopt -s nullglob
, ou[ -e "$i" ] || [ -L "$i" ] || continue
l'intérieur de la boucle.OriginalL'auteur
Essayez d'utiliser
Je n'ai pas vous donner de l'-1, mais il est évident pour moi pourquoi vous l'avez obtenu. Pourquoi ne pas donner comme réponse
alias bla ls ; bla
? La question qui a été posée était d'écrire l'algorithme, de ne pas trouver certains commande, qui fait la même chose quels
mais n'est pas appeléls
.Romascanu: Oh... ok, mais à partir de "j'ai reçu une assignation de ne pas utiliser de trouver ou de ls et de faire le travail", j'ai compris que tout était assez bon, sauf à trouver et ls ^^
Sur l'autre main peut-être que sa mission doit s'exécuter sur un système Solaris, AIX ou hp-ux, pas Linux. 🙂 Laissez-moi vous rassurer, il n'y a pas de
tree
de commande disponible par défaut sur non-Linuces etc.Romascanu: hehehe ok, je comprends votre point de vue 😉
OriginalL'auteur
Ci-dessous est une implémentation possible:
Comme un exercice que vous pouvez penser à comment modifier le script ci-dessus pour imprimer des chemins d'accès aux fichiers (au lieu de juste en retrait de fichier/dirnames), éventuellement, de se débarrasser de
pushd
/popd
(et de la nécessité pour le deuxième paramètre$2
) dans le processus.D'ailleurs, notez l'utilisation de
test XYZ && command
qui est totalement équivalente àif test XYZ ; then command ; fi
(c'est à dire exécutercommand
sitest XYZ
de réussite). Notez également quetest XYZ
est équivalent à[ XYZ ]
, c'est à dire la-dessus est équivalent àif [ XYZ ] ; then command ; fi
. Notez également qu'un point-virgule;
peut être remplacé par un saut de ligne, elles sont équivalentes.Supprimer la
test -e "$file" &&
condition (sortir de laecho
) et voir ce qui se passe.Supprimez les guillemets autour des
"$file"
et voir ce qui se passe lorsque le répertoire dont le contenu vous êtes à la liste contient les noms de fichiers avec des espaces entre eux. Ajouterset -x
en haut du script (ou invoquer celle-ci commesh -x scriptname.sh
au lieu de cela) pour activer la sortie de débogage et voir ce qui se passe dans le détail (pour rediriger la sortie de débogage dans un fichier, exécutezsh -x scriptname.sh 2>debugoutput.txt
).Aussi liste des fichiers cachés (par exemple,
.bashrc
):Notez l'utilisation de
!=
(comparaison de chaîne) au lieu de-ne
(comparaison numérique.)Une autre technique consisterait à frayer sous-coquille au lieu d'utiliser
pushd
/popd
:Noter que sur certains shell implémentations il est difficile de limite (~4k) sur le nombre de caractères qui peut être passé comme argument à
for
(ou à tout builtin, ou commande externe pour cette question.) Depuis le shell développe, en ligne,*
pour une liste de tous les fichiers correspondants avant de l'effectuer réellementfor
sur elle, vous pouvez exécuter des ennuis si*
est développée à l'intérieur d'un répertoire avec un grand nombre de fichiers (même problème que vous pourrez rencontrer lors de l'exécution, direls *
dans le même répertoire, par exemple, obtenez une erreur commeCommand too long
.)shopt -s dotglob
à la liste des fichiers cachés.pas de portable.
.*
(ou.?*
de sauter.
au large de la chauve-souris) fait le truc très bien et est portable aussi.OriginalL'auteur
Puisque c'est pour le bash, c'est une surprise que cela n'a pas déjà été dit:
(globstar valable à partir de bash 4.0+)
C'est tout.
Le slash
/
est là pour sélectionner uniquement dirs.Option
globstar
active le**
(recherche recursivelly).Option
nullglob
supprime un*
lorsqu'elle correspond à aucun fichier/dir.Option
dotglob
inclut les fichiers qui commencent avec un point (fichiers cachés).OriginalL'auteur
La
du
commande liste des sous-répertoires de manière récursive.Je ne suis pas sûr si vide répertoires obtenir une mention, bien que
OriginalL'auteur
Comme Mark A dit que vous pouvez utiliser
echo *
pour obtenir une liste de tous les fichiers dans le répertoire courant.La
test
ou[]
commande/builtin a une option pour tester si un fichier est un répertoire.Appliquer la récursivité et vous avez terminé.
echo
,for
sera glob, donc, OP pouvez utiliserfor file in * ; do ... ; done
.OriginalL'auteur
et il n'entre pas dans les répertoires et ne donne pas la liste des fichiers texte
il le FAIT entrer répertoires, et l'OP n'a rien dit à propos des fichiers texte (ou tous les fichiers en dehors de répertoires). Je ne vais pas fixer les répertoires avec des espaces.
Trop mauvais. C'était presque une grande réponse, mais ne possède pas les informations dont j'ai besoin (comme un n00b) à bricoler avec elle. Ressemble exactement à une autre chaîne de bash-foo pour moi.
Si vous n'aimez pas une réponse écrite dans un bash à une question demandant bash parce que c'est trop bashy? Ce n'est pas le site pour vous.
OriginalL'auteur
Techniquement, ni trouver ni ls sont utilisés par find2perl|perl ou File::Find directement.
ls
oufind
Évidemment. Mais puisque tout le sérieux des réponses ont obtenu moins que de la incroyable de la rétroaction, c'est quelque chose... moins graves. (En fait, j'allais écrire un clone de
find
en C et un shell script qui compile+fonctionne, mais a décidé que c'était trop d'effort pour faire une blague.)OriginalL'auteur
Basé sur cette réponse; utilisation options d'environnement désiré pour l'expansion de comportement:
**
avecglobstar
(Bash 4.0 ou plus récent)dotglob
**/*/
si il n'y a pas de correspondance avecnullglob
et ensuite utiliser
printf
par%q
formatage de la directive de citer les noms de répertoire de caractères spéciaux:donc si vous avez des répertoires comme
has space
ou même contenant un saut de ligne, vous obtiendrez de sortie commeavec un répertoire par ligne.
OriginalL'auteur