Imprimer la date de la dernière modification d'un fichier dans Bash

147

Je n'arrive pas à trouver comment imprimer la date d'un fichier. Je suis jusqu'à présent capable d'imprimer tous les fichiers dans un répertoire, mais je dois imprimer les dates avec.

Je sais que je dois joindre un format de date avec l'écho de l'entrée, mais tout ce que je ne trouve pas le bon format.

echo "Please type in the directory you want all the files to be listed"

read directory 

for entry in "$directory"/*
do
  echo "$entry"
done
Hokerie
la source
2
read -p "Veuillez taper le répertoire dans
lequel

Réponses:

146

Vous pouvez utiliser la stat commande

stat -c %y "$entry"

Plus d'informations

% y heure de la dernière modification, lisible par l'homme
Steven Penny
la source
for entry in "$directory"/* do stat -c%y "$entry" done Ça ne marche pas. Imprime la statistique: opérande manquant dans le terminal
Hokerie
Hm, est-ce que ça pourrait être mon unbuntu? Savez-vous quelles sont les conditions d'utilisation stat?
Hokerie
33
Notez que sur OS X (Mac), c'est stat -f "%m%t%Sm %N" filename(voir les man stat exemples pour plus de détails)
Olie
3
Notez que sur BSD, la statcommande a une syntaxe différente. Mon cas pour FreeBSD: stat -f %Sm -t %F" "%R filename.
Sopalajo de Arrierez
229

La commande «date» n'est-elle pas beaucoup plus simple? Pas besoin de awk, stat, etc.

date -r <filename>

Pensez également à consulter la page de manuel pour le formatage de la date; par exemple avec un format de date et d'heure courant:

date -r <filename> "+%m-%d-%Y %H:%M:%S"
mmond
la source
11
Beaucoup plus simple que d'utiliser stat / more available.
Ing
11
Il semble que BSD (ou du moins OS X) datene l'ait pas. Il -rest simplement utilisé pour fournir un horodatage au formatage. Vous devrez utiliser la date GNU pour obtenir cette fonctionnalité.
Waleed Khan
4
Sur OSX: datestat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007
3
Sous OS X 10.10, date -r <filename> fonctionne comme annoncé, bien que la page de manuel ne décrive aucun argument <filename>.
gotofritz le
3
Dans macOS 10.13, il date [-r seconds | filename]est entièrement documenté dans la manpage et fonctionne comme prévu.
Echelon
14

Sous OS X, j'aime que ma date soit au format de YYYY-MM-DD HH:MMdans la sortie du fichier.

Donc, pour spécifier un fichier, j'utiliserais:

stat -f "%Sm" -t "%Y-%m-%d %H:%M" [filename]

Si je veux l'exécuter sur une gamme de fichiers, je peux faire quelque chose comme ceci:

#!/usr/bin/env bash
for i in /var/log/*.out; do
  stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i"
done

Cet exemple s'imprimera la dernière fois que j'ai exécuté la sudo periodic daily weekly monthlycommande car elle référence les fichiers journaux.


Pour ajouter les noms de fichiers sous chaque date, j'exécuterais plutôt ce qui suit:

#!/usr/bin/env bash
for i in /var/log/*.out; do
  stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i"
  echo "$i"
done

Le résultat serait le suivant:

2016-40-01 16:40
/var/log/daily.out
2016-40-01 16:40
/var/log/monthly.out
2016-40-01 16:40
/var/log/weekly.out

Malheureusement, je ne sais pas comment empêcher le saut de ligne et conserver le nom du fichier ajouté à la fin de la date sans ajouter plus de lignes au script.


PS - J'utilise en #!/usr/bin/env bashtant qu'utilisateur Python de jour, et j'ai différentes versions de bashinstallées sur mon système au lieu de#!/bin/bash

Danijel-James W
la source
Au cas où vous n'auriez pas compris la partie de saut de ligne, l'indicateur -e est disponible pour le programme d'écho. Exemple d' utilisation pourrait être: echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile.". Dans votre cas, cela pourrait être: echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i." ``
Thoth
14

Le mieux est

date -r filename +"%Y-%m-%d %H:%M:%S"
rishi
la source
Cette réponse est un double de stackoverflow.com/a/20807343/6320039
Ulysse BN
@UlysseBN non, c'est légèrement différent. Il préconise un meilleur format de date.
iconoclaste
6

En ajoutant à la réponse @StevePenny, vous voudrez peut-être couper la partie qui n'est pas si lisible par l'homme:

stat -c%y Localizable.strings | cut -d'.' -f1
fotanus
la source
3

Je voulais obtenir la date de modification d'un fichier au YYYYMMDDHHMMSSformat. Voici comment je l'ai fait:

date -d @$( stat -c %Y myfile.css ) +%Y%m%d%H%M%S

Explication. C'est la combinaison de ces commandes:

stat -c %Y myfile.css # Get the modification date as a timestamp
date -d @1503989421 +%Y%m%d%H%M%S # Convert the date (from timestamp)
Fabien Snauwaert
la source
2

EDITED: il s'avère que j'avais oublié les citations nécessaires pour $entryimprimer correctement et ne pas donner l'erreur "aucun fichier ou répertoire de ce type". Merci à tous de m'avoir aidé!

Voici mon code final:

    echo "Please type in the directory you want all the files to be listed with last modified dates" #bash can't find file creation dates

read directory

for entry in "$directory"/*

do
modDate=$(stat -c %y "$entry") #%y = last modified. Qoutes are needed otherwise spaces in file name with give error of "no such file"
modDate=${modDate%% *} #%% takes off everything off the string after the date to make it look pretty
echo $entry:$modDate

S'imprime comme ceci:

/home/joanne/Dropbox/cheat sheet.docx:2012-03-14
/home/joanne/Dropbox/Comp:2013-05-05
/home/joanne/Dropbox/Comp 150 java.zip:2013-02-11
/home/joanne/Dropbox/Comp 151 Java 2.zip:2013-02-11
/home/joanne/Dropbox/Comp 162 Assembly Language.zip:2013-02-11
/home/joanne/Dropbox/Comp 262 Comp Architecture.zip:2012-12-12
/home/joanne/Dropbox/Comp 345 Image Processing.zip:2013-02-11
/home/joanne/Dropbox/Comp 362 Operating Systems:2013-05-05
/home/joanne/Dropbox/Comp 447 Societal Issues.zip:2013-02-11
Hokerie
la source
2

Pour les sauts de ligne, j'ai modifié votre code pour obtenir quelque chose sans saut de ligne.

#!/bin/bash
for i in /Users/anthonykiggundu/Sites/rku-it/*; do
   t=$(stat -f "%Sm"  -t "%Y-%m-%d %H:%M" "$i")
   echo $t : "${i##*/}"  # t only contains date last modified, then only filename 'grokked'- else $i alone is abs. path           
done
Anton Kiggundu
la source
1

Si le nom du fichier n'a pas d'espaces:

ls -l <dir> | awk '{print $6, " ", $7, " ", $8, " ", $9 }'

Ceci s'imprime au format suivant:

 Dec   21   20:03   a1.out
 Dec   21   20:04   a.cpp

Si les noms de fichiers ont de l'espace (vous pouvez utiliser la commande suivante pour les noms de fichiers sans espaces également, cela semble compliqué / moche que l'ancien):

 ls -l <dir> | awk '{printf ("%s %s %s ",  $6,  $7, $8); for (i=9;   i<=NF; i++){ printf ("%s ", $i)}; printf ("\n")}'
Facture
la source
Ah, je vois! Cela fonctionne principalement, sauf pour les fichiers avec des espaces dans les noms. Y a-t-il une solution à cela?
Hokerie
En fait, je l'ai essayé à nouveau, et cela ne fonctionne pas ... il s'avère que j'essayais un répertoire qui avait des noms de fichiers sans espaces. = / Modifié ma réponse ci
Hokerie
quand vous dites que cela ne fonctionne pas, pouvez-vous dire quelle est l'erreur? cela fonctionne pour moi lorsque je l'ai exécuté sur mon système.
Projet de loi
J'ai un "aucun fichier ou répertoire".
Hokerie
C'est parce que vous avez passé une valeur <dir>qui n'existe pas ... le code est parfaitement bien.
Projet de loi
0

Vous pouvez utiliser:

ls -lrt filename |awk '{print "%02d",$7}'

Cela affichera la date sur 2 chiffres.

Si entre 1 et 9, il ajoute le préfixe «0» et se convertit en 01 - 09.

J'espère que cela répond aux attentes.

Yoga Nathan
la source