перечислить все файлы новее, чем указанная временная метка, и отсортировать их

8

Я хочу перечислить все файлы (отсортированные по дате), которые новее, чем отметка времени, в формате только 20130207003851в каталоге / tmp. Подкаталоги могут быть опущены.

Использование SUSE Linux Enterprise Server 11.

Выходной формат должен быть

S0002948.LOG Feb  7 03:28 
S0002935.LOG Feb  7 05:58 
S0002952.LOG Feb  7 09:58 
S0002940.LOG Feb  7 11:58 

find / tmp -newermt "7 февраля 2013" -ls перечисляет файлы, которые я хочу, но

  • как я могу использовать метку времени в формате 20130207003851
  • как я могу отсортировать вывод?
  • как я могу отображать только имя файла и дату. Сначала имя файла, а затем дата?

PS Я не хочу использовать сенсорный, чтобы создать справочный файл для поиска

PSS

find -newermt "20130207003851" -ls
find: I cannot figure out how to interpret `20130207003851' as a date or time
Радек
источник
Что 2013007000385должно представлять? Я думаю, 2013 год - это год, но как пройти 007000385до 7 февраля?
Жиль "ТАК - перестань быть злым"
@ Жиль: Предполагается 20130207003851. Не правильно скопировал или ... извините за это.
Радек

Ответы:

10

findподдерживает множество форматов ввода даты . Простейший формат для получения - ГГГГММДД ЧЧ: ММ: СС. У вас уже есть цифры в правильном порядке, все, что вам нужно сделать, это извлечь первую группу ( ${timestamp%??????}: взять все, кроме последних 6 символов;: ${timestamp#????????}взять все, кроме первых 8 символов), и продолжать, добавляя пунктуацию, затем следующую группу как вы идете вместе.

timestamp=20130207003851
timestring=${timestamp%??????}; timestamp=${timestamp#????????}
timestring="$timestring ${timestamp%????}"; timestamp=${timestamp#??}
timestring="$timestring:${timestamp%??}:${timestamp#??}"

В bash (и ksh и zsh), но не в ash, вы можете использовать более читаемую ${STRING_VARIABLE:OFFSET:LENGTH}конструкцию.

timestring="${timestamp:0:8} ${timestamp:8:2}:${timestamp:10:2}:${timestamp:12:2}"

Чтобы отсортировать файлы по дате, распечатайте имена файлов с предшествующими датами и отсортируйте их, а затем удалите префикс даты. Используйте -printfдля управления форматом вывода. печатает часть времени модификации, определяемого ; если есть , вы получите количество секунд с начала эпохи Unix. Ниже я печатаю три столбца, разделенных табуляцией: время в сортируемом формате, имя файла и время в удобочитаемом формате; удаляет первый столбец, и вызов заменяет вкладку достаточным количеством пробелов, чтобы вместить все ожидаемые имена файлов (настройте 40 по желанию). В этом коде предполагается, что в именах файлов нет новых строк или вкладок.%TXXX@cut -f 2-expand

find -maxdepth 1 -type f \
     -newermt "$timestring" -printf '%T@\t%f\t%Tb %Td %TH:%TM\n' |
sort -k1n |
cut -f 2- |
expand -t 40
Жиль "ТАК - перестань быть злым"
источник
только часть поиска find -newermt "$timestring" -printf '%M@\t%f %Mb %Md %MH:%MM\n'дает мне забавный вывод-rwxrwxrwx@ S0002975.LOG -rwxrwxrwxb -rwxrwxrwxd -rwxrwxrwxH:-rwxrwxrwxM
Radek
@Radek Извините, это %Tдля mtime, %Mэто разрешения.
Жиль "ТАК - перестань быть злым"
Прекрасный. Работает плавно. Мой окончательный код - find /tmp -maxdepth 1 -type f -newermt "20130207 00:38:51" -printf '%T@\t%f-%Tb %Td %TH:%TM\n' | sort -k1n | cut -f 2-я разделил имя файла и время, -потому что я буду захватывать вывод в php и использовать - как разделитель. Огромное спасибо.
Радек
@ Жиль, это круто, но если ты объяснишь временную строку, это поможет больше ...
Рахул Патил
@RahulPatil Готово. Я также добавил более читабельный метод bash.
Жиль "ТАК - перестань быть злым"
5

С zsh:

zmodload zsh/stat
newer() {
  local t
  zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY && (( t >= timestamp ))
}
timestamp=20130207003851
print -rl -- /tmp/*(D.Om+newer)

В newerфункции возвращает истинные файлы новее $timestamp(обратите внимание , что zsh«s zstatне поддерживают субсекундную точность , хотя).

Затем все, что мы делаем, - это используем zshквалификаторы глобинга: Dвключать точечные файлы, .рассматривать только обычные файлы, Omупорядочивать по времени модификации и +newerвызывать newerфункцию, чтобы определить, какой файл выбрать.

Если вы также хотите отобразить временные метки файла, вы можете изменить newerна:

newer() {
  local t
  zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY &&
    REPLY+=$'\t'$t &&
    (( t >= timestamp ))
}

Обратите внимание, что результат генерации имени файла будет включать метки времени, что означает, что вы больше не можете использовать их в качестве имен файлов.

Стефан Шазелас
источник
это не сработает ssh, например.
evandrix