Как в Linux найти файлы с датами модификации НЕ старше данного файла?

Согласно GNU, кажется, что дата модификации точна только до второго уровня. У меня очень высокоскоростная система, которая генерирует множество файлов в каталог (со скоростью миллисекунды). Я пытаюсь отслеживать новые сгенерированные файлы и отображать имена файлов на терминале.

В настоящее время я использую

touch .file
sleep 1
find -type f -newer .file

чтобы найти файлы, измененные после создания .file. Однако, поскольку система работает с очень высокой частотой, параметр -newer в find, по-видимому, не может перехватывать файлы, которые изменяются/создаются в то же «время» (с точностью до секунд), что и новые touched .file. Чтобы уточнить, что я имею в виду, скажем, я коснулся файла в 01:02:03 AM, новый файл создается в 01:02:03:02 AM (02 миллисекунды после .file). find проигнорирует миллисекунды и сделает вывод, что они созданы одновременно. В результате этот новый файл не newer, чем .file, поэтому игнорируется.

Что такое обходной путь? Я думаю об использовании ! -older, к сожалению, find не имеет такой возможности. Я не хочу писать собственную версию find, чтобы уменьшить размер кода. Какие-либо предложения?


person return 0    schedule 28.04.2016    source источник
comment
А как насчет -not?   -  person Benjamin W.    schedule 29.04.2016
comment
Время модификации не является и не должно рассматриваться как атомарные идентификаторы транзакций. Не могли бы вы переместить/переименовать обработанные файлы, чтобы всегда знать, какие из них ожидают обработки?   -  person that other guy    schedule 29.04.2016
comment
@thatotherguy Мне очень нравится эта идея. К сожалению, эти файлы должны быть доступны только для чтения. Есть ли другой способ пометить файлы, не касаясь их?   -  person return 0    schedule 29.04.2016
comment
Вы можете коснуться фиктивных файлов в другом каталоге или с другим расширением, например. for file in *; do if [[ -f ~/processed_files/$file ]]; then echo "Already processed"; else process "$file"; > ~/processed_files/$file; fi; done.   -  person that other guy    schedule 29.04.2016


Ответы (1)


Лучше всего было бы генерировать имена файлов с идентификатором и использовать фильтр find на его основе.

Возвращаясь к вашему вопросу, вы можете попробовать следующее:

touch .file
find . -type f -printf "%T@ %p\0" |\
  awk -v RS="\0" -v reftime=$(find . -name .file -printf "%T@") \
      '$1>=reftime {print substr($0,index($0," ")+1)}'

%T@ %p\0 выводит время последней модификации в секундах с 1 января 1970 года, 00:00 по Гринвичу, с дробной частью. За ним следует пробел и имя файла.

\0 используется как разделитель для большей безопасности: команда не сломается, если имена файлов содержат специальные символы \n " и т.д.

awk используется для сравнения времени последнего изменения и печатает имена файлов с временем последнего изменения, более новым или равным времени последнего изменения .file

Благодаря printf каждая запись равна time + + filename. Естественно, первым полем будет $1: время последней модификации.

В моем тесте на моем Debian %T@ раз имеют фиксированную длину. Я мог бы заменить index($0," ")+1 на 22

В моем debian дробная часть всегда равна 0 (возможно, проблема с точностью), поэтому в моем случае будут напечатаны все файлы со временем последнего изменения в той же секунде, что и .file: даже те, которые созданы немного раньше .file в течение той же секунды .

person Jay jargot    schedule 28.04.2016