web-dev-qa-db-fra.com

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

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

Je sais que je dois joindre un format de date avec l'écho de l'entrée, mais je ne parviens pas à trouver le format correct.

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

read directory 

for entry in "$directory"/*
do
  echo "$entry"
done
97
Hokerie

Vous pouvez utiliser la commande stat

stat -c %y "$entry"

Plus d'informations

% y heure de la dernière modification, lisible par l’homme 
106
Steven Penny

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

date -r <filename>

En outre, envisagez de consulter la page man pour connaître le formatage de la date; par exemple avec un format de date et heure commun:

date -r <filename> "+%m-%d-%Y %H:%M:%S"
165
mmond

Sur OS X, j'aime bien que ma date soit au format YYYY-MM-DD HH:MM dans la sortie du fichier.

Donc, pour spécifier un fichier, je voudrais utiliser:

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

Si je veux l'exécuter sur une plage 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 imprimera la dernière fois que j'ai exécuté la commande Sudo periodic daily weekly monthly car elle fait référence aux fichiers journaux.


Pour ajouter les noms de fichiers sous chaque date, je lancerais plutôt ceci:

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

La sortie serait la suivante:

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 #!/usr/bin/env bash car je suis un utilisateur Python par jour et j'ai différentes versions de bash installées sur mon système au lieu de #!/bin/bash

12
Danijel-James W

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

stat -c%y Localizable.strings | cut -d'.' -f1
6
fotanus

Le meilleur est date -r filename +"%Y-%m-%d %H:%M:%S

3
rishi

Je voulais obtenir la date de modification d'un fichier au format YYYYMMDDHHMMSS. 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)
2
Fabien Snauwaert

EDITED: s’est avéré que j’avais oublié les guillemets nécessaires pour $entry afin d’imprimer correctement et de ne pas donner l’erreur "aucun fichier ou répertoire de ce type". Merci beaucoup pour votre aide!

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

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
2
Hokerie

Pour les sauts de ligne, j'ai édité votre code pour obtenir quelque chose sans sauts 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
2
Anton Kiggundu

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

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

Cela 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 aussi, cela semble plus 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")}'
1
Bill

Vous pouvez utiliser:

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

Cela affichera la date en 2 chiffres.

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

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

0
Yoga Nathan