Bash'de bir dosyanın son değiştirilme tarihini yazdırın


151

Bir dosyanın tarihini nasıl yazdıracağımı bulamıyorum. Şimdiye kadar bir dizindeki tüm dosyaları yazdırabiliyorum, ancak bununla tarihleri ​​yazdırmam gerekiyor.

Girişin yankısı ile bir tarih formatı eklemem gerektiğini biliyorum, ancak tek şey doğru formatı bulamıyorum.

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
read -p "Lütfen tüm dosyaların listelenmesini istediğiniz dizini yazın" dizini
CousinCocaine

Yanıtlar:


148

stat Komutu kullanabilirsiniz

stat -c %y "$entry"

Daha fazla bilgi

% y son değişiklik zamanı, insan tarafından okunabilir

for entry in "$directory"/* do stat -c%y "$entry" done Çalışmıyor.
Statü

Hm, benim unbuntum olabilir mi? Kullanmanın gerekliliklerinin ne olduğunu biliyor musunuz stat?
Hokerie

34
OS X'te (Mac) bunun stat -f "%m%t%Sm %N" filename( daha fazla ayrıntı için man stat örneklere bakın)
Olie

3
BSD'de statkomutun farklı bir sözdizimi olduğunu unutmayın. FreeBSD için My durum: stat -f %Sm -t %F" "%R filename.
Sopalajo de Arrierez

238

'Tarih' komutu çok daha basit değil mi? Awk, stat vb. Gerekmez.

date -r <filename>

Ayrıca, tarih biçimlendirmesi için man sayfasına bakmayı düşünün ; örneğin ortak tarih ve saat formatıyla:

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

11
Stat / more available kullanmaktan çok daha basit.
Ing

11
Görünüşe göre BSD (veya en azından OS X'lerde) datebuna sahip değil. Onun -rsadece biçimine bir zaman damgası sağlamak için kullanılır. Bu işlevi elde etmek için GNU tarihini kullanmanız gerekecek.
Waleed Khan

4
OSX kullanımında: tarihstat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007

3
OS X 10.10'da tarih -r <dosya adı> belirtildiği gibi çalışır, ancak man sayfası herhangi bir <dosya adı> bağımsız değişkenini açıklamaz.
gotofritz

3
MacOS 10.13'te sayfada date [-r seconds | filename]tam olarak belgelenmiştir manve beklendiği gibi çalışır.
Echelon


14

OS X'te, tarihimin YYYY-MM-DD HH:MMdosya çıktısının biçiminde olmasını seviyorum .

Bu yüzden kullanacağım bir dosya belirtmek için:

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

Bir dizi dosyada çalıştırmak istersem, şöyle bir şey yapabilirim:

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

Bu örnek sudo periodic daily weekly monthly, günlük dosyalarına başvururken komutu en son çalıştırdığımda yazdıracak .


Dosya adlarını her tarihin altına eklemek için bunun yerine aşağıdakileri çalıştırırdım:

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

Çıktı şöyleydi:

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

Ne yazık ki, betiğe daha fazla satır eklemeden satır sonunun nasıl önleneceğinden ve dosya adını tarihin sonuna nasıl ekleyeceğimi bilmiyorum.


Not - #!/usr/bin/env bashGün geçtikçe Python kullanıcısı olduğum için kullanıyorum ve bashsistemimde bunun yerine farklı sürümleri yüklü#!/bin/bash


Satır sonu kısmını çözmediyseniz, yankı programı için -e bayrağı mevcuttur. Örnek kullanım olabilir: echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile.". Sizin durumunuzda echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i."
şunlar

6

@StevePenny cevabına ekleyerek, insan tarafından okunamayan kısmı kesmek isteyebilirsiniz:

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

3

Bir dosyanın değişiklik tarihini YYYYMMDDHHMMSSformatta almak istedim . İşte böyle yaptım:

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

Açıklama. Bu komutların birleşimidir:

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

DÜZENLENMİŞ: $entryDoğru şekilde yazdırmak için gereken teklifleri unuttuğum ve "böyle bir dosya veya dizin yok" hatası vermediğim ortaya çıktı. Bana yardım ettiğiniz için hepinize çok teşekkür ederim!

İşte son kodum:

    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

Şöyle yazdırır:

/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

Satır sonları için, kodunuzu satır sonu olmayan bir şey alacak şekilde düzenledim.

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

Dosya adında boşluk yoksa:

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

Bu, aşağıdaki formatta yazdırılır:

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

Dosya adlarında boşluk varsa (boşluksuz dosya adları için aşağıdaki komutu da kullanabilirsiniz, yalnızca öncekinden daha karmaşık / çirkin görünür):

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

Ah, anlıyorum! Bu, adlarında boşluklar olan dosyalar dışında çoğunlukla işe yarar. Bunun için bir çözüm var mı?
Hokerie

Aslında, tekrar denedim ve işe yaramadı ... boşluksuz dosya adlarına sahip bir dizini denediğim ortaya çıktı. = / Cevabımı aşağıda
düzenledim

işe yaramaz dediğinizde, hata nedir diyebilir misiniz? sistemimde çalıştırdığımda benim için çalışıyor.
Bill

"Böyle bir dosya veya dizin yok" var.
Hokerie

Bunun nedeni, değeri <dir>olmayan bir değeri iletmiş olmanızdır .... kod tamamen iyidir.
Bill

0

Kullanabilirsiniz:

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

Bu, tarihi 2 basamaklı olarak gösterecektir.

1 ile 9 arasındaysa buna "0" ön eki ekler ve 01 - 09'a dönüştürür.

Umarım bu beklentiyi karşılar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.