Boucler sur les annuaires en Bash
J'ai une question fondamentale sur la façon bash fonctionne, et une question d'ordre pratique.
Question fondamentale: supposons que je suis dans un répertoire qui comporte trois sous-répertoires: a, b, et c.
poule le code
for dir in $(ls)
do
echo $dir
done
crache:
a b c
a b c
a b c
je.e, dir
toujours stocke une liste de tous les fichiers/répertoires dans mon cwd
. Ma question est: pourquoi dans le monde serait-ce pratique? À mon avis, il est beaucoup plus utile et intuitif pour avoir dir
stocker chaque élément à la fois, j'.e je ne veux pas avoir de sortie
a
b
c
Aussi, comme l'une des réponses - c'est mal d'utiliser for dir in $(ls)
, mais lorsque j'utilise for dir in $(ls -l)
- je obtenir encore plus de copies de a b c
(plus qu'il existe des répertoires/fichiers dans le cwd). Pourquoi est-ce?
Ma deuxième question pratique: comment faire une boucle sur tous les répertoires (pas les fichiers!) dans mon cwd
que de commencer avec un capital W? J'ai commencé avec
for dir in `ls -l W*`
mais cela échoue, car a) la raison dans la question 1 et b) parce qu'il n'a pas d'exclure des fichiers. Suggestions apprécié.
Vous êtes de droite. Quand j'ai essayer ce code j'ai été en utilisant
$(ls)
, mais quand j'ai écrit la question, j'ai changé $(ls)
à $(ls -l)
parce que cela semble être la façon dont c'est fait, partout où j'ai regardé. Je suppose que le résultat serait le même et je suis surpris qu'il ne l'est pas.Pourquoi êtes-vous surpris d'apprendre que la sortie de
ls -l
est différent par rapport à juste ls
? Le paramètre change son comportement (type man ls
pour plus de détails): -l
vous donne longue sortie, y compris les autorisations, la propriété, la date, etc. C'est un encore plus grand non-non à l'analyse, parce que sa production peut varier considérablement en fonction de la mise en œuvre et de votre locale
. ls -l
est ce que vous pouvez utiliser sur la ligne de commande, mais jamais dans un script comme celui-ci. Si vous avez vu le code qui analyse sa sortie dans votre environnement, vous devez contacter l'auteur et de demander qu'ils soient corrigés.Bon, je veux dire que je suis surpris de voir que le format de la sortie est si différent. La sortie de la
$(ls)
cas donne trois rangées de a b c
, alors que la sortie de $(ls -l)
les rendements de trois lignes, chacune contenant la sortie désirée (a
, suivie par b
, suivie par c
). J'ai compris que les commandes sont ... similaire? ... devrait donc produire raisonnablement ... similaire? ... de sortie.Double Possible de stackoverflow.com/questions/2107945/...
OriginalL'auteur alexvas | 2013-04-06
Vous devez vous connecter pour publier un commentaire.
Jamais analyser les données en sortie de
ls
comme ceci (Pourquoi vous ne devriez pas analyser la sortie de ls(1)).Aussi, votre syntaxe est incorrecte. Vous ne voulez pas dire
()
, tu veux dire$()
.Cela étant dit, faire une boucle sur les répertoires commençant par W vous ferait (ou utilisez le
find
de commande au lieu de cela, en fonction de votre scénario):Comme pour la sortie de the evil ls-boucle, il ne devrait pas ressembler à ça. C'est le résultat attendu et montre pourquoi vous ne voulez pas utiliser la commande ls en premier lieu:
for dir in $(ls)
est faux. Je suppose quels
retourne un tableau stockant les répertoires et les fichiers dans mon mdc, puisfor
serait en boucle sur eux. Pourquoi est-ce qui se passe?Il ne veut pas retourner un tableau, il imprime une chaîne de caractères sur la sortie standard qui vous capture avec le
$()
de la syntaxe. D'autres que je ne peux pas répondre à votre question parce que votre boucle for ne doit pas imprimer une matrice comme vous l'avez posté, basé sur le scénario que vous avez mentionné.Mise à jour de ma réponse à démontrer que la sortie doit effectivement ressembler vous attend en premier lieu, vous voudrez peut-être essayer à nouveau.
Ah! Mais il y a une différence entre la façon dont vous et je reprends les noms des répertoires! J'ai utilisé
echo $dir
et vous avez utiliséecho ${dir}
. En effet, si j'utilise votre syntaxe puis-je obtenir de sortie similaire à la vôtre, et je suis certain que si vous utilisez la syntaxe, alors vous obtiendrez de mon résultat. Ce qui ne les accolades veux dire, alors?Non, ils sont équivalents dans ce cas. Les accolades sont nécessaires dans de tels scénarios:
foo=hello; echo "$fooworld"; echo "${foo}world"
(dans le cas des variables nom sont ambigus). Je vous suggère de lire le Advanced Bash Scripting Guide et la BashGuide pour en savoir plus sur les bases, les pièges courants et, fondamentalement, tout ce que vous devez/voulez savoir sur l'écriture de scripts bash.OriginalL'auteur Adrian Frühwirth
Cela devrait fonctionner:
Être récursive dans les sous-répertoires aussi, utiliser
globstar
:Vous pouvez faire @Adrian Frühwirths' méthode récursive des sous-répertoires à l'aide de
globstar
trop:De Manuel De Bash:
OriginalL'auteur Jahid
Eh bien, vous savez ce que vous voyez n'est pas ce que vous attendez. La sortie que vous voyez n'est pas de la commande echo, mais à partir de la commande dir.
Essayez ce qui suit:
OriginalL'auteur user1587276