Linux: file più recente in una directory

Alla ricerca di un comando che restituirà il singolo file più recente in una directory.

Non vedo un parametro limite per ls …

 ls -Art | tail -n 1 

Non molto elegante, ma funziona.

 ls -t | head -n1 

Questo comando fornisce effettivamente l’ultimo file modificato nella directory di lavoro corrente.

Questa è una versione ricorsiva (cioè trova il file aggiornato più di recente in una determinata directory o in una qualsiasi delle sue sottodirectory)

 find $DIR -type f -printf "%[email protected] %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1 

Modifica: usa -f 2- invece di -f 2 come suggerito da Kevin

Io uso:

ls -ABrt1 --group-directories-first | tail -n1

Mi dà solo il nome del file, escluse le cartelle.

ls -lAtr | tail -1

Le altre soluzioni non includono i file che iniziano con '.' .

Questo comando includerà anche '.' e '..' , che può o non può essere quello che vuoi:

ls -latr | tail -1

Variante in cortocircuito basata sulla risposta di dmckee:

 ls -t | head -1 

Mi piace echo *(om[1]) (syntax zsh ) dato che dà solo il nome del file e non richiama nessun altro comando.

Personalmente preferisco usare il minor numero di comandi bash non incorporati che posso (per ridurre il numero di costose fork e exec syscalls). Per ordinare per data è necessario chiamare ls . Ma l’uso della head non è veramente necessario. Io uso il seguente one-liner (funziona solo sui sistemi che supportano le named pipe):

 read newest < <(ls -t *.log) 

o per ottenere il nome del file più vecchio

 read oldest < <(ls -rt *.log) 

(Occupati dello spazio tra i due segni "<"!)

Se sono necessari anche i file nascosti, è ansible aggiungere un argomento.

Spero che questo possa aiutare.

La soluzione di ricerca / ordinamento funziona benissimo fino a quando il numero di file diventa molto grande (come un intero file system). Utilizza awk invece per tenere traccia del file più recente:

 find $DIR -type f -printf "%[email protected] %p\n" | awk ' BEGIN { recent = 0; file = "" } { if ($1 > recent) { recent = $1; file = $0; } } END { print file; }' | sed 's/^[0-9]*\.[0-9]* //' 
 ls -t -1 | sed '1q' 

Mostrerà l’ultimo elemento modificato nella cartella. Accoppia con grep per trovare le ultime voci con le parole chiave

 ls -t -1 | grep foo | sed '1q' 

prova questo semplice comando

 ls -ltq  | head -n 1 

Se vuoi il nome del file – ultima modifica, percorso = /ab/cd/*.log

Se vuoi il nome della directory – ultima modifica, percorso = / ab / cd / * /

Una nota sull’affidabilità:

Dato che il carattere di nuova riga è valido come qualsiasi in un nome di file, qualsiasi soluzione che si basa su linee come quelle basate su head / tail sono difettose.

Con GNU ls , un’altra opzione è usare l’ --quoting-style=shell-always e un array bash :

 eval "files=($(ls -t --quoting-style=shell-always))" ((${#files[@]} > 0)) && printf '%s\n' "${files[0]}" 

(aggiungere -A se si desidera considerare anche i file nascosti).

Se si desidera limitare a file normali (ignorare directory, fifo, dispositivi, symlink, socket …), è necessario ricorrere a GNU find .

Con bash 4.4 o successivi (per readarray -d ) e GNU coreutils 8.25 o successivi (per cut -z ):

 readarray -t -d '' < <( LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%[email protected]/%f\0' | sort -rzn | cut -zd/ -f2) ((${#files[@]} > 0)) && printf '%s\n' "${files[0]}" 

O ricorsivamente:

 readarray -t -d '' < <( LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%[email protected]%p\0' | sort -rzn | cut -zd/ -f2-) 

La cosa migliore sarebbe usare zsh e i suoi qualificatori glob anziché bash per evitare tutto questo fastidio:

Il più recente file normale nella directory corrente:

 printf '%s\n' *(.om[1]) 

Compresi quelli nascosti:

 printf '%s\n' *(D.om[1]) 

Secondo più recente:

 printf '%s\n' *(.om[2]) 

Verifica l'età del file dopo la risoluzione dei link simbolici:

 printf '%s\n' *(-.om[1]) 

ricorsivamente:

 printf '%s\n' **/*(.om[1]) 

Inoltre, con il sistema di completamento ( compinit e co) abilitato, Ctrl + X m diventa un completatore che si espande nel file più recente.

Così:

  vi Ctrl + X m 

Ti farebbe modificare il file più recente (avrai anche la possibilità di vederlo prima di premere Invio ).

  vi Alt + 2 Ctrl + X m 

Per il secondo file più recente.

  vi * .c Ctrl + X m 

per il più nuovo file c .

  vi * (.) Ctrl + X m 

per il file normale più recente (non directory, né fifo / dispositivo ...) e così via.

ricorsivamente:

 find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head 

Tutte quelle soluzioni ls / tail funzionano perfettamente bene per i file in una directory – ignorando le sottodirectory.

Per includere tutti i file nella ricerca (in modo ricorsivo), è ansible trovare trova. Gioele suggerì di ordinare l’output di ricerca formattato. Ma attenzione con gli spazi bianchi (il suo suggerimento non funziona con gli spazi bianchi).

Questo dovrebbe funzionare con tutti i nomi di file:

 find $DIR -type f -printf "%[email protected] %p\n" | sort -n | sed -r 's/^[0-9.]+\s+//' | tail -n 1 | xargs -I{} ls -l "{}" 

Questo ordina per mtime, vedi man find:

 %Ak File's last access time in the format specified by k, which is either `@' or a directive for the C `strftime' function. The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems. @ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part. %Ck File's last status change time in the format specified by k, which is the same as for %A. %Tk File's last modification time in the format specified by k, which is the same as for %A. 

Quindi basta sostituire %T con %C per ordinare per ctime.

Trovare il file più aggiornato in ogni directory secondo uno schema, ad esempio le sottodirectory della directory di lavoro che hanno un nome che termina con “tmp” (senza distinzione tra maiuscole e minuscole):

 find . -iname \*tmp -type d -exec sh -c "ls -lArt {} | tail -n 1" \; 

Presumendo che non ti importa dei file nascosti che iniziano con a .

 ls -rt | tail -n 1 

Altrimenti

 ls -Art | tail -n 1 

usando l’opzione ricorsiva R .. potresti considerare questo come un miglioramento per le buone risposte qui

 ls -arRtlh | tail -50 

Dovevo farlo anche io e ho trovato questi comandi. questi funzionano per me:

Se si desidera l’ultimo file in base alla data di creazione nella cartella (tempo di accesso):

 ls -Aru | tail -n 1 

E se vuoi l’ultimo file che ha dei cambiamenti nel suo contenuto (modifica del tempo):

 ls -Art | tail -n 1