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 ...
ls -Art | tail -n 1
Pas très élégant, mais ça marche.
ls -t | head -n1
Cette commande donne en fait le dernier fichier modifié dans le répertoire de travail actuel.
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
J'utilise:
ls -ABrt1 --group-directories-first | tail -n1
Il ne me donne que le nom du fichier, à l'exclusion des dossiers.
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
Variante raccourcie basée sur la réponse de dmckee:
ls -t | head -1
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]* //'
J'aime echo *(om[1])
(syntaxe zsh
) car cela donne simplement le nom du fichier et n'appelle aucune autre commande.
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.
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.
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/* /
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
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'
Récursivement:
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
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
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.
ls -Frt | grep "[^/]$" | tail -n 1
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" \;