พิมพ์วันที่แก้ไขล่าสุดของไฟล์ใน Bash


147

ฉันไม่สามารถหาวิธีพิมพ์วันที่ของไฟล์ได้ ฉันสามารถพิมพ์ไฟล์ทั้งหมดในไดเรกทอรีได้ แต่ฉันต้องพิมพ์วันที่ด้วย

ฉันรู้ว่าฉันต้องแนบรูปแบบวันที่ด้วยเสียงสะท้อนของรายการ แต่ทั้งหมดฉันไม่พบรูปแบบที่ถูกต้อง

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
อ่าน -p "กรุณาพิมพ์ในไดเรกทอรีที่คุณต้องการไฟล์ทั้งหมดที่จะแสดง" ไดเรกทอรี
CousinCocaine

คำตอบ:


146

คุณสามารถใช้ stat คำสั่ง

stat -c %y "$entry"

ข้อมูลเพิ่มเติม

เวลา% y ของการแก้ไขครั้งล่าสุดมนุษย์อ่านได้

for entry in "$directory"/* do stat -c%y "$entry" done ใช้งานไม่ได้ พิมพ์สถิติ: ไม่มีตัวถูกดำเนินการในเทอร์มินัล
Hokerie

หืมมันเป็นอูบุนตูของฉันได้ไหม คุณรู้หรือไม่ว่าข้อกำหนดการใช้statคืออะไร?
Hokerie

33
โปรดทราบว่าใน OS X (Mac) มันเป็นstat -f "%m%t%Sm %N" filename(ดูman stat ตัวอย่างสำหรับรายละเอียดเพิ่มเติม)
Olie

3
โปรดทราบว่าใน BSD statคำสั่งมีไวยากรณ์ที่แตกต่าง กรณีของฉันสำหรับ stat -f %Sm -t %F" "%R filenameFreeBSD:
Sopalajo de Arrierez

228

คำสั่ง 'date' ไม่ง่ายกว่านี้หรือไม่ ไม่จำเป็นต้อง awk, stat ฯลฯ

date -r <filename>

ลองพิจารณาที่หน้า manสำหรับการจัดรูปแบบวันที่ เช่นที่มีรูปแบบวันที่และเวลาทั่วไป:

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

11
ง่ายกว่ามากจากนั้นใช้สถิติ / มีมากขึ้น
Ing

11
ดูเหมือนว่า BSD (หรืออย่างน้อย OS X) dateจะไม่มีสิ่งนี้ มัน-rเป็นเพียงการใช้เพื่อให้การประทับเวลาในการจัดรูปแบบ คุณจะต้องใช้วันที่ของ GNU เพื่อรับฟังก์ชั่นนี้
Waleed Khan

4
ในการใช้ OSX: วันที่stat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007

3
ใน OS X 10.10 date -r <filename> ทำงานตามที่โฆษณาไว้แม้ว่าหน้า man จะไม่อธิบายอาร์กิวเมนต์ <filename> ใด ๆ
gotofritz

3
ใน macOS 10.13 date [-r seconds | filename]มีเอกสารครบถ้วนในmanหน้าและทำงานตามที่คาดไว้
ระดับ

14

ใน OS X ฉันชอบวันที่ของฉันที่จะอยู่ในรูปแบบของ YYYY-MM-DD HH:MMผลลัพธ์สำหรับไฟล์

ดังนั้นเพื่อระบุไฟล์ฉันจะใช้:

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

ถ้าฉันต้องการเรียกใช้ในช่วงของไฟล์ฉันสามารถทำสิ่งนี้:

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

ตัวอย่างนี้จะพิมพ์ออกมาในครั้งสุดท้ายที่ฉันรันsudo periodic daily weekly monthlyคำสั่งเนื่องจากอ้างอิงไฟล์บันทึก


หากต้องการเพิ่มชื่อไฟล์ภายใต้แต่ละวันฉันจะเรียกใช้สิ่งต่อไปนี้แทน:

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

ผลลัพธ์จะเป็นดังนี้:

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

น่าเสียดายที่ฉันไม่แน่ใจว่าจะป้องกันการแตกบรรทัดและคงชื่อไฟล์ต่อท้ายวันที่โดยไม่ต้องเพิ่มบรรทัดเพิ่มเติมในสคริปต์


PS - ฉันใช้#!/usr/bin/env bashเพราะฉันเป็นผู้ใช้ Python ในแต่ละวันและbashติดตั้งรุ่นต่างๆในระบบของฉันแทน#!/bin/bash


ในกรณีที่คุณยังไม่พบส่วนที่แบ่งบรรทัดแฟล็ก -e จะพร้อมใช้งานสำหรับโปรแกรม echo ตัวอย่างการใช้งานอาจเป็น: echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile.". ในกรณีของคุณมันอาจจะเป็น: echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i." `
Thoth


6

การเพิ่มคำตอบ @StevePenny คุณอาจต้องการตัดส่วนที่ไม่เป็นที่มนุษย์อ่านได้:

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

3

ฉันต้องการได้รับวันที่แก้ไขไฟล์ในYYYYMMDDHHMMSSรูปแบบ นี่คือวิธีที่ฉันทำ:

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

คำอธิบาย มันเป็นการรวมกันของคำสั่งเหล่านี้:

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

แก้ไข: ปรากฎว่าฉันลืมคำพูดที่จำเป็นสำหรับ$entryการพิมพ์อย่างถูกต้องและไม่ให้ข้อผิดพลาด "ไม่มีไฟล์หรือไดเรกทอรี" ขอบคุณมากที่ช่วยฉัน!

นี่คือรหัสสุดท้ายของฉัน:

    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

พิมพ์ออกมาเช่นนี้

/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

สำหรับการขึ้นบรรทัดใหม่ฉันแก้ไขโค้ดของคุณเพื่อรับสิ่งที่ไม่มีการขึ้นบรรทัดใหม่

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

หากชื่อไฟล์ไม่มีช่องว่าง:

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

พิมพ์นี้เป็นรูปแบบต่อไปนี้:

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

หากชื่อไฟล์มีช่องว่าง (คุณสามารถใช้คำสั่งต่อไปนี้สำหรับชื่อไฟล์ที่ไม่มีช่องว่างได้เพียง แต่ดูเหมือนซับซ้อน / น่าเกลียดกว่าเดิม):

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

อ่าฉันเข้าใจแล้ว! ส่วนใหญ่ใช้งานได้ยกเว้นไฟล์ที่มีช่องว่างในชื่อ มีวิธีแก้ปัญหาสำหรับสิ่งนั้นหรือไม่?
Hokerie

ที่จริงแล้วฉันลองอีกครั้งและมันใช้งานไม่ได้ ... ปรากฎว่าฉันลองใช้ไดเรกทอรีที่มีชื่อไฟล์โดยไม่มีช่องว่าง = / แก้ไขคำตอบของฉันด้านล่าง
Hokerie

เมื่อคุณบอกว่ามันใช้งานไม่ได้คุณจะพูดว่าอะไรคือข้อผิดพลาด? มันทำงานสำหรับฉันเมื่อฉันดำเนินการในระบบของฉัน
Bill

ฉันได้รับ "ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว"
Hokerie

นั่นเป็นเพราะคุณผ่านค่า<dir>ที่ไม่มีอยู่ .... รหัสนั้นสมบูรณ์แบบ
Bill

0

คุณสามารถใช้ได้:

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

จะแสดงวันที่เป็นตัวเลข 2 หลัก

ถ้าระหว่าง1ถึง9จะเพิ่มส่วนนำหน้า "0" และแปลงเป็น 01 - 09

หวังว่าสิ่งนี้เป็นไปตามความคาดหมาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.