Stampa l'ultima data modificata di un file in Bash


147

Non riesco a trovare come stampare la data di un file. Sono finora in grado di stampare tutti i file in una directory, ma ho bisogno di stampare le date con esso.

So che devo allegare un formato data con l'eco della voce, ma non riesco a trovare il formato corretto.

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

read directory 

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

2
leggi -p "Digita la directory in cui vuoi elencare tutti i file"
CousinCocaine,

Risposte:


146

Puoi usare il stat comando

stat -c %y "$entry"

Ulteriori informazioni

% y tempo dell'ultima modifica, leggibile dall'uomo

for entry in "$directory"/* do stat -c%y "$entry" done Non funziona Stampa stat: operando mancante nel terminal
Hokerie

Hm, potrebbe essere il mio unbuntu? Sai quali sono i requisiti per l'utilizzo stat?
Hokerie,

33
Nota che su OS X (Mac) è stat -f "%m%t%Sm %N" filename(vedi man stat esempi per maggiori dettagli)
Olie

3
Notare che su BSD il statcomando ha una sintassi diversa. Il mio caso per FreeBSD: stat -f %Sm -t %F" "%R filename.
Sopalajo de Arrierez,

229

Il comando 'date' non è molto più semplice? Non c'è bisogno di awk, stat, ecc.

date -r <filename>

Inoltre, considera la pagina man per la formattazione della data; ad esempio con il formato comune di data e ora:

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

11
Molto più semplice quindi usare stat / more available.
Ing

11
Sembra che BSD (o almeno OS X) datenon abbia questo. La sua -rè solo utilizzato per fornire un timestamp formato. Dovrai usare la data GNU per ottenere questa funzionalità.
Waleed Khan,

4
Su OSX utilizzare: datastat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007,

3
Su OS X 10.10 la data -r <nomefile> funziona come pubblicizzato, sebbene la pagina man non descriva alcun argomento <nomefile>.
gotofritz,

3
In macOS 10.13 date [-r seconds | filename]è completamente documentato nella manpagina e funziona come previsto.
Echelon,

14

Su OS X, mi piace che la mia data sia nel formato YYYY-MM-DD HH:MMdell'output del file.

Quindi per specificare un file vorrei usare:

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

Se voglio eseguirlo su una gamma di file, posso fare qualcosa del genere:

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

Questo esempio verrà stampato l'ultima volta che ho eseguito il sudo periodic daily weekly monthlycomando poiché fa riferimento ai file di registro.


Per aggiungere i nomi dei file in ciascuna data, esegui invece quanto segue:

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

L'output sarebbe stato il seguente:

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

Purtroppo non sono sicuro di come impedire l'interruzione di riga e mantenere il nome del file aggiunto alla fine della data senza aggiungere più righe allo script.


PS: lo uso #!/usr/bin/env bashcome un utente Python di giorno e ho versioni diverse di bashinstallate sul mio sistema anziché#!/bin/bash


Nel caso non abbiate capito la parte di interruzione di riga, il flag -e è disponibile per il programma eco. Esempio di utilizzo potrebbe essere: echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile.". Nel tuo caso potrebbe essere: echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i." `
Thoth


6

Aggiungendo alla risposta @StevePenny, potresti voler tagliare la parte non così leggibile dall'uomo:

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

3

Volevo ottenere la data di modifica di un file in YYYYMMDDHHMMSSformato. Ecco come l'ho fatto:

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

Spiegazione. È la combinazione di questi comandi:

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

EDITED: risulta che avevo dimenticato le virgolette necessarie per $entrypoter stampare correttamente e non dare l'errore "nessun file o directory". Grazie mille per avermi aiutato!

Ecco il mio codice finale:

    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

Stampa in questo modo:

/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

Per le interruzioni di riga ho modificato il codice per ottenere qualcosa senza interruzioni di riga.

#!/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

1

Se il nome del file non ha spazi:

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

Questo viene stampato nel seguente formato:

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

Se i nomi dei file hanno spazio (puoi usare il seguente comando anche per i nomi dei file senza spazi, sembra complicato / brutto del precedente):

 ls -l <dir> | awk '{printf ("%s %s %s ",  $6,  $7, $8); for (i=9;   i<=NF; i++){ printf ("%s ", $i)}; printf ("\n")}'

Ah, capisco! Funziona principalmente, ad eccezione dei file con gli spazi nei nomi. C'è una soluzione per questo?
Hokerie,

In realtà, l'ho provato di nuovo, e non funziona ... risulta che stavo provando una directory che aveva nomi di file senza spazi. = / Modificata la mia risposta di seguito
Hokerie

quando dici che non funziona, puoi dire qual è l'errore? funziona per me quando l'ho eseguito sul mio sistema.
Bill

Ho ottenuto un "nessun file o directory".
Hokerie

Questo perché hai passato un valore di <dir>cui non esiste .... il codice è perfettamente a posto.
Bill

0

Puoi usare:

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

Questo visualizzerà la data in 2 cifre.

Se tra 1 e 9 aggiunge il prefisso "0" e lo converte in 01 - 09.

Spero che questo soddisfi le aspettative.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.