toccare tutte le cartelle in una directory


13

Sto cercando di aggiornare i timestamp di tutte le cartelle nel CWD usando questo:

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

Ma non sembra funzionare. Qualche idea sul perché?

Risposte:


21

Tutte le risposte finora (così come il tuo esempio nella domanda) presumono che tu voglia touchtutto nella directory, anche se hai detto "tocca tutte le cartelle". Se risulta che la directory contiene file e cartelle e si desidera aggiornare solo le cartelle, è possibile utilizzare find:

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

O se l' findimplementazione non supporta i non standard -mindepth/ -maxdepthpredicati:

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

Questo:

$ touch -c -- */

Dovrebbe funzionare nella maggior parte delle shell tranne che:

  • si touch collegherà anche a directory in aggiunta a directory semplici
  • ometterà quelli nascosti
  • se non c'è directory o link simbolico alla directory, sarebbe creare un file chiamato *in gusci diversi csh, tcsh, zsh, fisho il guscio Thompson (che segnalare un errore, invece). Qui, stiamo usando -cper aggirare il problema, anche se potrebbe ancora essere touchchiamato un file non di directory *.

Con zsh, touchsolo per le directory, comprese quelle nascoste:

touch -- *(D/)

Di cosa tratta "{} \ +"?
javamonkey79,

3
Il {} \+è speciale findsintassi - leggi la pagina man per di più. Penso touch -c ./*/che funzionerebbe anche.
jw013,

2
È necessario includere -maxdepth 1nel comando, in modo che findnon ricorra nelle sottocartelle. OP sembra voler toccare solo quelle cartelle nel CWD, non le sottocartelle.
Steven lunedì

1
@ jw013 Sarebbe - continui ad attaccare buone idee alle risposte degli altri :)
Michael Mrozek

Perché dovresti sfuggire al personaggio +? Ci sono conchiglie che lo interpretano?
Witiko,

11

Provare

touch ./*

Evita il forciclo non necessario che genererebbe un nuovo processo per ogni singolo file e funziona per tutti i nomi di file, anche quelli con spazi o quelli che sembrano opzioni (come -t). L'unica volta in cui non funzionerebbe è se non ci sono file (non punti) nella directory, nel qual caso finiresti per creare un file chiamato *. Per evitare ciò, per il caso specifico della touchmaggior parte delle implementazioni è disponibile -cun'opzione (chiamata anche --no-createnelle versioni GNU) per non creare file inesistenti, ovvero

touch -c ./*

Vedi anche i riferimenti buone della risposta di jasonwryan così come questo uno .


1
Cosa succederà se hai 1 milione di cartelle nel CWD?
Steven lunedì

Se incontri problemi di tipo "lista argomenti troppo lunghi", probabilmente è meglio passare a strumenti "più pesanti" come find . -type d -maxdepth1 -print0 | xargs -0 touch, o alla risposta di MichaelMrozek sopra.
jw013,

7

Non dovresti tentare di analizzare l'output dils .

Inoltre, dovresti citare il tuo "$file"per catturare qualsiasi spazio bianco. Vedi http://www.grymoire.com/Unix/Quote.html

Qualcosa del genere potrebbe ottenere ciò che cerchi:

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

Vedi le prime due insidie ​​di Bash per una spiegazione più approfondita.


2
Chiudi ma non del tutto. A touch ./*dovrebbe funzionare nella maggior parte dei casi. Non è davvero necessario per il forciclo poiché touchpuò richiedere più file ed è necessario ./gestire i file con nomi come --helpcorrettamente. Questa è una buona risorsa in materia.
jw013

Perché '*' funziona?
javamonkey79,

@ javamonkey79 suo guscio globbing .
jw013

1
@ jw013 Ottimo punto: e grazie per il collegamento con le ruote.
Jasonwryan,

Si noti che *non acquisisce file e directory il cui nome inizia con un punto. Un modo per risolvere questo è abilitare l' dotglobopzione shell tramite shopt -s dotglob.
Witiko,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.