Wydrukuj datę ostatniej modyfikacji pliku w Bash

147

Nie mogę znaleźć sposobu na wydrukowanie daty pliku. Jak dotąd mogę wydrukować wszystkie pliki w katalogu, ale muszę wydrukować z nim daty.

Wiem, że muszę dołączyć format daty z echem wpisu, ale nie mogę znaleźć prawidłowego formatu.

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
źródło
2
read -p "Proszę wpisać katalog, w którym mają zostać wyświetlone wszystkie pliki" katalog
CousinCocaine

Odpowiedzi:

146

Możesz użyć stat polecenia

stat -c %y "$entry"

Więcej informacji

% y czasu ostatniej modyfikacji, czytelne dla człowieka
Steven Penny
źródło
for entry in "$directory"/* do stat -c%y "$entry" done Nie działa. Wyświetla statystykę: brakujący operand w terminalu
Hokerie
Hm, czy to może być moje unbuntu? Czy wiesz, jakie są wymagania związane z używaniem stat?
Hokerie
33
Zauważ, że na OS X (Mac) jest stat -f "%m%t%Sm %N" filename(zobacz man stat przykłady, aby uzyskać więcej informacji)
Olie
3
Zauważ, że na BSD statpolecenie ma inną składnię. Moja sprawa dla FreeBSD stat -f %Sm -t %F" "%R filename.
Sopalajo de Arrierez
228

Czy polecenie „data” nie jest dużo prostsze? Nie ma potrzeby używania awk, stat itp.

date -r <filename>

Rozważ również przejrzenie strony podręcznika systemowego pod kątem formatowania daty; na przykład ze wspólnym formatem daty i godziny:

date -r <filename> "+%m-%d-%Y %H:%M:%S"
mmond
źródło
11
O wiele prostsze niż użycie stat / more available.
Ing.
11
Wygląda na to, że BSD (lub przynajmniej OS X) datetego nie ma. Jego -rwłaśnie wykorzystane do zapewnienia znacznik czasu do formatu. Będziesz musiał użyć daty GNU, aby uzyskać tę funkcję.
Waleed Khan,
4
W systemie OSX: datastat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007
3
W OS X 10.10 date -r <nazwa pliku> działa zgodnie z zapowiedzią, chociaż strona podręcznika nie opisuje żadnego argumentu <nazwa pliku>.
gotofritz
3
W macOS 10.13 date [-r seconds | filename]jest w pełni udokumentowany na manstronie i działa zgodnie z oczekiwaniami.
Echelon
14

W systemie OS X wolę, aby moja data była w formacie pliku YYYY-MM-DD HH:MMwyjściowego.

Aby więc określić plik, którego użyłbym:

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

Jeśli chcę uruchomić go na wielu plikach, mogę zrobić coś takiego:

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

Ten przykład zostanie wydrukowany, gdy ostatnio uruchomiłem sudo periodic daily weekly monthlypolecenie, ponieważ odwołuje się do plików dziennika.


Aby dodać nazwy plików pod każdą datą, uruchomiłbym zamiast tego następujące:

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

Wynik byłby następujący:

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

Niestety nie jestem pewien, jak zapobiec złamaniu wiersza i zachować nazwę pliku na końcu daty bez dodawania kolejnych wierszy do skryptu.


PS - używam, #!/usr/bin/env bashponieważ jestem użytkownikiem Pythona w ciągu dnia i bashzamiast tego mam różne wersje zainstalowanego w moim systemie#!/bin/bash

Danijel-James W.
źródło
W przypadku, gdy nie odgadłeś części podziału wiersza, flaga -e jest dostępna dla programu echo. Przykład użycia mogą być: echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile.". W twoim przypadku może to być: echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i." `
Thoth
14

Najlepsze jest

date -r filename +"%Y-%m-%d %H:%M:%S"
rishi
źródło
Ta odpowiedź jest duplikatem strony stackoverflow.com/a/20807343/6320039
Ulysse BN
@UlysseBN nie, to jest trochę inne. Opowiada się za lepszym formatem daty.
ikonoklast
6

Dodając do odpowiedzi @StevePenny, możesz chcieć wyciąć część niezbyt czytelną dla człowieka:

stat -c%y Localizable.strings | cut -d'.' -f1
fotanus
źródło
3

Chciałem uzyskać datę modyfikacji YYYYMMDDHHMMSSpliku w formacie. Oto jak to zrobiłem:

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

Wyjaśnienie. To kombinacja tych poleceń:

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
źródło
2

EDYTOWANE: okazuje się, że zapomniałem cudzysłowów potrzebnych $entrydo poprawnego wydruku i nie podawałem błędu „nie ma takiego pliku lub katalogu”. Dziękuję bardzo za pomoc!

Oto mój ostateczny kod:

    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

Wydruki wyglądają następująco:

/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
źródło
2

W przypadku podziałów wierszy zmodyfikowałem Twój kod, aby uzyskać coś bez podziałów wierszy.

#!/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
źródło
1

Jeśli nazwa pliku nie zawiera spacji:

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

Wydrukuje się w następującym formacie:

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

Jeśli nazwy plików mają spację (możesz użyć następującego polecenia również dla nazw plików bez spacji, po prostu wygląda to na skomplikowane / brzydkie niż poprzednie):

 ls -l <dir> | awk '{printf ("%s %s %s ",  $6,  $7, $8); for (i=9;   i<=NF; i++){ printf ("%s ", $i)}; printf ("\n")}'
Rachunek
źródło
O, rozumiem! To w większości działa, z wyjątkiem plików ze spacjami w nazwach. Czy jest na to rozwiązanie?
Hokerie
Właściwie spróbowałem ponownie i nie działa ... Okazuje się, że próbowałem katalog, który miał nazwy plików bez spacji. = /
Edytowałem
kiedy mówisz, że to nie działa, czy możesz powiedzieć, jaki jest błąd? działa dla mnie, gdy wykonałem go w moim systemie.
Bill
Otrzymałem „nie ma takiego pliku lub katalogu”.
Hokerie
Dzieje się tak, ponieważ przekazałeś wartość, <dir>której nie ma ... kod jest w porządku.
Bill
0

Możesz użyć:

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

Spowoduje to wyświetlenie daty w postaci 2 cyfr.

Jeśli od 1 do 9 , dodaje do niego przedrostek „0” i konwertuje na 01-09.

Mam nadzieję, że to spełnia oczekiwania.

Yoga Nathan
źródło