toucher tous les dossiers d'un répertoire

14

J'essaie de mettre à jour les horodatages de tous les dossiers du cwd en utilisant ceci:

for file in `ls`; do touch $file; done

Mais cela ne semble pas fonctionner. Des idées pourquoi?

javamonkey79
la source

Réponses:

21

Jusqu'à présent, toutes les réponses (ainsi que votre exemple dans la question) supposent que vous voulez touchtout dans le répertoire, même si vous avez dit "toucher tous les dossiers". S'il s'avère que le répertoire contient des fichiers et des dossiers et que vous souhaitez uniquement mettre à jour les dossiers, vous pouvez utiliser find:

$ find . -maxdepth 1 -mindepth 1 -type d -exec touch {} +

Ou si votre findapplication ne supporte pas les non-standard -mindepth/ -maxdepthprédicats:

$ find . ! -name . -prune -type d -exec touch {} +

Cette:

$ touch -c -- */

Devrait fonctionner dans la plupart des coquilles sauf que:

  • il fera également des touch liens symboliques vers des répertoires en plus des répertoires ordinaires
  • il omettra ceux cachés
  • s'il n'y a pas de répertoire ou lien symbolique dans le répertoire, il crée un fichier appelé *dans des coquilles autres que csh, tcsh, zsh, fishou la coquille Thompson (qui signale une erreur à la place). Ici, nous utilisons -cpour contourner cela, bien que cela puisse toujours être touchun fichier non-répertoire appelé *.

Avec zsh, vers les touchrépertoires uniquement, y compris les répertoires masqués:

touch -- *(D/)
Michael Mrozek
la source
À quoi sert le '{} \ +'?
javamonkey79
3
La syntaxe {} \+est spéciale find- lisez la page de manuel pour en savoir plus. Je pense que touch -c ./*/cela fonctionnerait aussi.
jw013
2
Vous devez inclure -maxdepth 1à la commande, afin que cela findne soit pas récurrent dans les sous-dossiers. OP semble vouloir toucher uniquement les dossiers du cwd, pas les sous-dossiers.
Steven lundi
1
@ jw013 Ce serait - vous continuez à attacher de bonnes idées aux réponses des autres :)
Michael Mrozek
Pourquoi voudriez-vous échapper au caractère +? Y a-t-il des coquilles qui l'interprètent?
Witiko
11

Essayer

touch ./*

Il évite la forboucle inutile qui engendrerait un nouveau processus pour chaque fichier unique et fonctionne pour tous les noms de fichiers, même ceux avec des espaces ou ceux qui ressemblent à des options (comme -t). La seule fois où cela ne fonctionnera pas, c'est si vous n'avez aucun fichier (non point) dans le répertoire, auquel cas vous finirez par créer un fichier nommé *. Pour éviter cela, pour le cas spécifique de la touchplupart des implémentations, vous avez une -coption (également appelée --no-createdans les versions GNU) pour ne pas créer de fichiers inexistants, c'est-à-dire

touch -c ./*

Voir aussi les bonnes références dans la réponse de jasonwryan ainsi que celle- ci .

jw013
la source
1
Que se passera-t-il si vous avez 1 million de dossiers dans le cwd?
Steven lundi
Si vous rencontrez des problèmes de type "liste d'arguments trop longue", il est probablement préférable de passer à des outils "plus lourds" comme find . -type d -maxdepth1 -print0 | xargs -0 touch, ou à la réponse de MichaelMrozek ci-dessus.
jw013
7

Vous nels devez pas essayer d'analyser la sortie de .

En outre, vous devez citer votre "$file"pour capturer n'importe quel espace blanc. Voir http://www.grymoire.com/Unix/Quote.html

Quelque chose comme ça pourrait réaliser ce que vous recherchez:

for file in *; do touch "$file"; done

Voir les deux premiers pièges de Bash pour une explication plus approfondie.

jasonwryan
la source
2
Fermer mais pas tout à fait. Un touch ./*devrait fonctionner dans la plupart des cas. Il n'y a vraiment pas besoin de la forboucle car touchpeut prendre plusieurs fichiers, et vous devez ./gérer les fichiers avec des noms comme --helpcorrectement. Ceci est une bonne ressource sur le sujet.
jw013
Pourquoi «*» fonctionne-t-il?
javamonkey79
@ javamonkey79 C'est un globbing de coquille .
jw013
1
@ jw013 Excellent point: et merci pour le lien wheeler.
jasonwryan
Notez que *ne capture pas les fichiers et répertoires dont le nom commence par un point. Une façon de résoudre ce problème consiste à activer l' dotgloboption shell via shopt -s dotglob.
Witiko
-1
for file in `find .`; do touch $file; done
mikematic
la source