web-dev-qa-db-fra.com

Obtenir le fichier le plus récent dans un répertoire sous Linux

Vous recherchez une commande qui renverra le fichier unique le plus récent dans un répertoire.

Ne voyant pas de paramètre limite à ls ...

128
ack
ls -Art | tail -n 1

Pas très élégant, mais ça marche.

197
dmckee
ls -t | head -n1

Cette commande donne en fait le dernier fichier modifié dans le répertoire de travail actuel. 

107
chaos

Il s’agit d’une version récursive (c’est-à-dire qu’elle trouve le fichier le plus récemment mis à jour dans un répertoire donné ou l’un de ses sous-répertoires)

find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1

Edit: utilisez -f 2- au lieu de -f 2 comme suggéré par Kevin

52
gioele

J'utilise:

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

Il ne me donne que le nom du fichier, à l'exclusion des dossiers.

9
user1195354

ls -lAtr | tail -1

Les autres solutions n'incluent pas les fichiers qui commencent par '.'.

Cette commande comprendra également '.' et '..', qui peuvent ou non correspondre à vos souhaits:

ls -latr | tail -1

7
Jared Oberhaus

Variante raccourcie basée sur la réponse de dmckee:

ls -t | head -1
5

La solution de recherche/tri fonctionne parfaitement jusqu'à ce que le nombre de fichiers devienne vraiment important (comme un système de fichiers complet). Utilisez awk à la place pour simplement garder une trace du fichier le plus récent:

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

J'aime echo *(om[1]) (syntaxe zsh) car cela donne simplement le nom du fichier et n'appelle aucune autre commande.

3
MikeB

Une note sur la fiabilité:

Comme le caractère de nouvelle ligne est aussi valide que n'importe quel nom de fichier, toute solution reposant sur lines , comme celle basée sur head/tail, est défectueuse.

Avec GNU ls, une autre option consiste à utiliser l'option --quoting-style=Shell-always et un tableau bash:

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

(ajoutez -A si vous souhaitez également prendre en compte les fichiers cachés).

Si vous voulez vous limiter aux fichiers normaux (sans tenir compte des répertoires, fifos, périphériques, liens symboliques, sockets ...), vous devez utiliser GNU find.

Avec bash 4.4 ou plus récent (pour readarray -d) et GNU coreutils 8.25 ou plus récent (pour cut -z):

readarray -t -d '' < <(
  LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%T@/%f\0' |
  sort -rzn | cut -zd/ -f2)

((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

Ou récursivement:

readarray -t -d '' < <(
  LC_ALL=C find . -name . -o -name '.*' -Prune -o -type f -printf '%T@%p\0' |
  sort -rzn | cut -zd/ -f2-)

Le mieux ici serait d’utiliser zsh et ses qualificatifs globaux au lieu de bash pour éviter tout ce problème:

Dernier fichier régulier du répertoire actuel:

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

Y compris les cachés:

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

Deuxième plus récent:

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

Vérifier l'âge du fichier après la résolution du lien symbolique:

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

Récursivement:

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

De plus, avec le système d’achèvement (compinit

pour le dernier fichier regular (pas de répertoire, ni fifo/device ...), etc.

3
Stephane Chazelas

Personnellement, je préfère utiliser le moins possible de commandes bash non intégrées (pour réduire le nombre d'appels système coûteux de type fork et exec). Pour trier par date, la ls devait être appelée. Mais l'utilisation de head n'est pas vraiment nécessaire. J'utilise le one-liner suivant (ne fonctionne que sur les systèmes prenant en charge les tubes nominatifs):

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

ou pour obtenir le nom du fichier le plus ancien

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

(Attention à l'espace entre les deux marques '<'!)

Si les fichiers cachés sont également nécessaires, un argument peut être ajouté.

J'espère que cela pourrait aider.

2
TrueY

essayez cette commande simple

ls -ltq  <path>  | head -n 1

Si vous voulez le nom du fichier - dernière modification, chemin = /ab/cd/*.log

Si vous voulez le nom du répertoire - dernière modification, chemin =/ab/cd/* /

1
RICHA AGGARWAL

en utilisant l'option récursive R .. vous pouvez considérer cela comme une amélioration pour de bonnes réponses 

ls -arRtlh | tail -50
1
mebada
ls -t -1 | sed '1q'

Affiche le dernier élément modifié du dossier. Associez-vous à grep pour rechercher les dernières entrées avec des mots clés.

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

Récursivement:

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

En supposant que vous ne vous souciez pas des fichiers cachés qui commencent par un .

ls -rt | tail -n 1

Autrement

ls -Art | tail -n 1
0
jasonleonhard

Toutes ces solutions ls/tail fonctionnent parfaitement pour les fichiers situés dans les sous-répertoires a directory.

Afin d'inclure tous les fichiers dans votre recherche (récursivement), find peut être utilisé. gioele a suggéré de trier la sortie de la recherche formatée. Mais soyez prudent avec les espaces blancs (sa suggestion ne fonctionne pas avec les espaces blancs).

Cela devrait fonctionner avec tous les noms de fichiers:

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

Cela trie par mtime, voir 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.

Il suffit donc de remplacer %T par %C pour trier par ctime.

0
basic6
ls -Frt | grep "[^/]$" | tail -n 1
0
João Fonseca

Recherche du fichier le plus récent dans chaque répertoire selon un modèle, par exemple. les sous-répertoires du répertoire de travail dont le nom se termine par "tmp" (insensibles à la casse):

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