Напечатайте дату последнего изменения файла в 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
Hokerie
источник
2
прочитайте -p «Пожалуйста, введите каталог, в котором вы хотите, чтобы все файлы были перечислены»
CousinCocaine

Ответы:

146

Вы можете использовать stat команду

stat -c %y "$entry"

Больше информации

% y время последней модификации, удобочитаемое человеком
Стивен Пенни
источник
for entry in "$directory"/* do stat -c%y "$entry" done Не работает Распечатывает статистику: пропавший операнд в терминале
Хокери
Хм, это может быть мой unbuntu? Знаете ли вы, каковы требования использования stat?
Хокери
33
Обратите внимание, что на OS X (Mac), это stat -f "%m%t%Sm %N" filename(см. man stat Примеры для более подробной информации)
Olie
3
Обратите внимание, что в BSD statкоманда имеет другой синтаксис. Мой случай для FreeBSD: stat -f %Sm -t %F" "%R filename.
Сопалахо де Арриерес
229

Разве команда date не намного проще? Нет необходимости в awk, stat и т. Д.

date -r <filename>

Кроме того, рассмотрите возможность просмотра форматирования даты на справочной странице ; например с общим форматом даты и времени:

date -r <filename> "+%m-%d-%Y %H:%M:%S"
mmond
источник
11
Намного проще, чем использовать stat / more.
Ing
11
Похоже, что BSD (или, по крайней мере, OS X) dateне имеет этого. Его -rпросто используют для предоставления метки времени для форматирования. Вы должны будете использовать дату GNU, чтобы получить эту функциональность.
Валид Хан
4
На OSX использовать: дата stat -f "%Sm" -t "%m%d%H%M%y" "${1}"
Michaelangel007
3
В OS X 10.10 date -r <имя_файла> работает так, как объявлено, хотя на странице руководства не описано ни одного аргумента <имя_файла>.
получил
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

Даниэль-Джеймс W
источник
Если вы не выяснили часть разрыва строки, для программы echo доступен флаг -e. Пример использования может быть: 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." `
Тот
14

Лучше всего

date -r filename +"%Y-%m-%d %H:%M:%S"
риши
источник
Этот ответ является дубликатом stackoverflow.com/a/20807343/6320039
Ulysse BN
@UlysseBN нет, это немного по-другому. Он выступает за лучший формат даты.
иконоборчество
6

Добавляя к ответу @StevePenny, вы, возможно, захотите вырезать не очень понятную для человека часть:

stat -c%y Localizable.strings | cut -d'.' -f1
fotanus
источник
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
Hokerie
источник
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")}'
Билл
источник
Ах я вижу! Это в основном работает, за исключением файлов с пробелами в именах. Есть ли решение для этого?
Хокери
На самом деле, я попробовал еще раз, и это не работает ... оказывается, я пробовал каталог, в котором были имена файлов без пробелов. = / Отредактировал мой ответ ниже
Хокери
когда вы говорите, что это не работает, вы можете сказать, в чем ошибка? это работает для меня, когда я выполнил это в моей системе.
Билл
Я получил "нет такого файла или каталога".
Хокери
Это потому, что вы передали значение, <dir>которого не существует .... код прекрасно.
Билл
0

Ты можешь использовать:

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

Это будет отображать дату в 2 цифры.

Если от 1 до 9 он добавляет префикс «0», он преобразуется в 01–09.

Надеюсь, что это соответствует ожиданиям.

Йога Натан
источник