Come elencare i file più vecchi di un giorno con "2015" nel nome file?


11

Voglio elencare tutti i file di registro che non appartengono oggi e solo i file che contengono 2015nei loro nomi.

Questi sono i comandi che ho provato:

find . -name 2015 -mtime +1 -exec  ls -ltrh  {} \;
find . -name *2015* -mtime +1 -exec  ls -ltrh  {} \;

L'output di entrambi è nulla, ma comunque, i file ci sono. C'è qualcosa di sbagliato in questi comandi e non capisco cosa. Qualsiasi aiuto sarebbe apprezzato.


La findparte mi sembra buona, ma ho anche avuto problemi con il -execparametro. Neanche io riuscivo a farlo funzionare. (Stavo cercando di spostare tutti i file jpg da una cartella alla sua directory principale attraverso di essa - e ho finito per farlo manualmente ...)
Byte Commander


@steeldriver Penso che sia davvero ciò che non va qui, dal momento che se ci fossero file nella directory corrente con il 2015loro nome (l'altro ovvio difetto del modo in cui è scritto il comando) sospetto che ci sarebbe un qualche tipo di output. Quindi potresti voler pubblicare una risposta al riguardo.
Eliah Kagan,

Risposte:


18

Il comando find . -name '*2015*' -mmin +1440 -lsprobabilmente farà quello che vuoi. Vedi sotto per i dettagli.

Il tuo primo comando ha avuto -name 2015. Non ha funzionato perché trova solo i file i cui nomi sono esattamente 2015 , senza altri caratteri.

Il tuo secondo comando, find . -name *2015* -mtime +1 -exec ls -ltrh {} \;potrebbe non essere riuscito per un paio di motivi:

1. I* caratteri non quotati vengono espansi dalla shell, quindi passati a find.

Se ci sono file direttamente contenuti nella directory corrente (quella in cui ti sei imbattuto quando hai eseguito quel find ...comando) i cui nomi contengono 2015(e non iniziano con a .), la shell si è espansa *2015*in un elenco di quei nomi di file, quindi è passata tale elenco come argomenti a find. Questo non è quello che vuoi - invece, vuoi passare *2015*letteralmente come argomento da trovare, in modo che find, e non la shell, possa trovare quali file corrispondono.

Per risolvere il problema, citare *2015*. Esistono tre modi comuni per farlo:

  • '*2015*'(cioè, find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(cioè, find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(cioè, find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Io suggerisco di scriverlo con virgolette singole come '*2015*', perché:

Ma in questo caso non importa. 'ed "entrambi trattano *lo stesso e l'espressione non è abbastanza complicata da essere \citata per renderla difficile da capire.

2. -mtime +1seleziona solo i file modificati due o più giorni fa.

Come man finddice:

       Numeric arguments can be specified as

       +n     for greater than n,

       -n     for less than n,

       n      for exactly n.
       -mtime n
              File's data was last modified n*24 hours ago.  See the  comments
              for -atime to understand how rounding affects the interpretation
              of file modification times.
       -atime n
              File was last accessed n*24 hours ago.  When  find  figures  out
              how  many  24-hour  periods  ago the file was last accessed, any
              fractional part is ignored, so to match -atime +1, a file has to
              have been accessed at least two days ago.

Supponiamo che un file sia stato modificato 47 ore fa. Per capire quanti periodi di 24 ore sono findarrotondati per eccesso : è un periodo di 24 ore fa. Ma -mtime +1corrisponde solo ai file i cui tempi di modifica sono strettamente superiori a un periodo di 24 ore fa. Pertanto, i file di ieri non corrispondono.

Vedi Perché find -mtime +1 restituisce solo file più vecchi di 2 giorni? per ulteriori informazioni, come suggerito da steeldriver .

Per trovare i file modificati l'ultima volta in qualsiasi momento più di 24 ore fa , suggerisco invece di stipularlo come 1440 minuti fa con -mmin +1440:

find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;

Alcuni lettori potrebbero chiedersi perché non ho citato {}. Alcune persone citano {}per ricordare agli umani che non è un'espressione per l' espansione del tutore . Le conchiglie in stile Bourne (come bash ) non richiedono {}che all'interno non vi sia nulla da quotare. Forse una shell non in stile Bourne la tratta in modo speciale; questo potrebbe essere il motivo per cui alcuni utenti lo citano. Ma c'è anche un'idea sbagliata che a volte si debba citare, {}quindi -execgestisce correttamente i nomi dei file con spazi. Quello; s false: con {}o '{}', findottiene gli stessi argomenti, poiché la shell rimuove le virgolette prima di passare '{}'afind. Per contrastare questo malinteso, non cito {}, ma è una questione di stile - se preferisci {}documentare come la shell non sta trattando {e }specialmente, va bene.

Ti consiglio anche di cambiare il tuo lscomando o (come ha suggerito muru ) di sostituirlo con findl' -lsazione. ls -ltrhprobabilmente non sta facendo ciò che intendi perché viene eseguito separatamente per ogni file trovato e quindi i flag -te -r, che specificano l'ordinamento, sono irrilevanti.

Sebbene l'output verrà formattato in modo leggermente diverso rispetto a ls -l, l'utilizzo -lsè più semplice e facile.

find . -name '*2015*' -mmin +1440 -ls

Oppure, se decidi che devi davvero elencare solo i nomi dei file (compresi i loro percorsi, relativamente a .), puoi semplicemente specificare nessuna azione, facendo -printin modo che venga usata l'azione predefinita :

find . -name '*2015*' -mmin +1440

1
Bella risposta accurata! almeno con GNU find, c'è anche la newerXYsintassi, che accetta gli argomenti del calendario ad es. -newermt 'yesterday'e! -newermt 'yesterday'
steeldriver

Sai cosa ? Sei fantastico. @ Eliah Kagan
rɑːdʒɑ

Grazie stell driver, questa è un'ottima informazione dal link per sapere. Ma nel mio caso in quanto è il registro dell'applicazione da vecchi file dell'applicazione non ha modo di essere modificato. Grazie ancora
rɑːdʒɑ

2

Cita l'espressione e ti suggerisco di citare anche le parentesi

find . -name "2015" -mtime +1 -exec  ls -ltrh  '{}' \;

o

find . -name "*2015*" -mtime +1 -exec  ls -ltrh  '{}' \;

non è necessario passare i file che trovi a ls

find . -name "*2015*" -mtime +1

Forse limitare l'utilizzo -type f? E se lsdeve essere usato, suggerisci di usare -ls.
muru,

1
certo, tutti i buoni suggerimenti. Non sono sicuro di cosa voglia l'OP e credo che la fonte del problema sia la mancanza di virgolette attorno al modello di ricerca "-name".
Pantera

2

In zsh , puoi usare i qualificatori glob (questa è una caratteristica zsh unica, non disponibile in altre shell come bash).

ls -ltr *2015*(m+1)

Questo elenca solo i file nella directory corrente; per attraversare ricorsivamente le directory , usare

ls -ltr **/*2015*(m+1)

Con find, -name 2015trova solo i file il cui nome è esattamente 2015. -name *2015*Funziona solo se non ci sono file il cui nome contiene 2015nella directory corrente, perché la shell espande il modello *2015*prima che findvenga invocato. Devi citare il modello:

find -name '*2015*' -mtime +1 …

Si noti che entrambi find -mtime +1e zsh *(m+1)trovano file che hanno almeno 48 ore , non file più vecchi di oggi. Il segno più significa "rigorosamente più di" e il numero di giorni viene arrotondato per difetto. Per trovare file di almeno 24 ore, utilizzare -mtime +0o (m+0).

Se si desidera trovare i file modificati l'ultima volta ieri o prima , è possibile utilizzare findcon il -newermtpredicato :

find -name '*2015*' ! -newermt 'today 0:00' …

Non esiste un modo davvero conveniente per eseguire questo test in zsh.

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.