Вопрос или проблема
Мы работаем над рекурсивной логикой для поиска всех файлов по шаблону, а затем обрабатываем по одному файлу за раз, который пришел ранее, и затем переходим к следующему файлу из списка для обработки.
Требуется создать список файлов на основе времени создания/поступления на системе Unix, но нижеуказанный комментарий перечисляет файлы на основе их имен, как кажется.
Пожалуйста, помогите, если мы можем перечислить имена файлов на основе их создания ИЛИ поступления, или временной метки в имени файла в порядке, и затем обрабатывать файл соответственно через рекурсию.
Команда, которую мы используем:
find . -type f -name "FILE_NAME*.CSV"
Но это не работает так, как ожидается. Пожалуйста, посоветуйте.
find
сам по себе действительно не сортирует. Однако GNU find может выводить временную метку вместе с именем файла с помощью -printf
, а затем вы можете отсортировать с помощью sort
. Например, так:
$ find doc -type f -printf "%T@ %p\n" |sort -n | head
783376319.0000000000 doc/article.txt
919286022.0000000000 doc/INTRO
919286124.0000000000 doc/README
938460221.0000000000 doc/rose94.ps
939135511.0000000000 doc/htmlpost.sh
1054224216.0000000000 doc/infopost.sh
1135958198.0000000000 doc/rose94.pdf
1218547491.0000000000 doc/rbash.1
Это mtime в секундах с начала эпохи, с наносекундами.
Тем не менее, обратите внимание, что ни одна из трех общих временных меток не соответствует “созданию” файла, так как atime (возможно) изменяется при любом доступе, mtime изменяется при любой записи, а ctime изменяется при любом изменении inode (включая записи). %T
как указано выше использует mtime, который может либо работать, либо не работать для вас.
(Кроме того, использование основанного на строках вывода может привести к сбою, если какое-либо из имен файлов содержит символы новой строки, не делайте этого.)
В любом случае, я бы избегал попыток сортировать файлы, чтобы найти новые, а лучше создавал новые файлы в отдельном каталоге, а затем перемещал их в конечное место после обработки. Таким образом, вы будете знать, что все в каталоге промежуточного хранения новое и нуждается в обработке, а все, чего там нет, уже было обработано.
С помощью zsh
,
files=( **/FILE_NAME*.CSV(ND.Om) )
Можно создать список обычных файлов, имя которых соответствует этому шаблону, найденному в текущем рабочем каталоге или ниже, O
рганизованных по времени последней m
одификации (времени создания содержимого файла¹) от старых к новым.
Затем вы можете перебрать их с помощью:
for file ($files) что-то с $file
¹ Многие системы также записывают время рождения (в файловых системах, которые это поддерживают, что в настоящее время является нормой), но API для их получения, если они имеются, не является переносимым (и, по крайней мере, на системах на основе Linux, относительно недавним), и zsh не имеет опции сортировки файлов на основе этого. Эта временная метка также часто менее полезна, чем время изменения, так как файлы никогда не создаются целиком за один раз и могут быть созданы задолго до того, как они становятся доступными по данному пути (под данным именем) и, возможно, с совершенно другим содержимым.
Ответ или решение
Для решения вашей задачи по перечислению файлов в порядке их создания или поступления можно использовать команду find
в сочетании с другими утилитами в Unix-системе. Команда find
сама по себе не сортирует файлы, но вы можете извлечь информацию о времени их создания, а затем отсортировать эти данные.
Шаг 1: Использование команды find
и sort
Вы можете выполнить следующую команду, чтобы найти все файлы, соответствующие вашему шаблону, и отсортировать их по времени последней модификации:
find . -type f -name "FILE_NAME*.CSV" -printf "%T@ %p\n" | sort -n
Этот пример использует -printf
для вывода времени последней модификации (mtime
) в формате, удобном для сортировки (число секунд с начала эпохи UNIX), за которым следует путь к файлу. sort -n
затем сортирует строки по времени.
Примечание: Необходимо учитывать, что mtime
— это время последней модификации файла, а не время его создания. В некоторых файловых системах (например, в некоторых версиях ext4 на Linux) может быть доступно время создания (или "birth time"), но это не всегда реализуется одинаково на всех системах.
Шаг 2: Извлечение файлов в порядке создания
Если вам нужно получить файлы в виде списка и обработать их по одному, вы можете использовать цикл while
:
find . -type f -name "FILE_NAME*.CSV" -printf "%T@ %p\n" | sort -n | while read line; do
# Извлекаем путь к файлу
file=$(echo $line | awk '{print $2}')
# Ваш код обработки файла здесь
echo "Обработка файла: $file"
done
Шаг 3: Альтернативный способ с zsh
Если вы используете zsh
, вы можете воспользоваться его расширенными возможностями для сортировки файлов по времени модификации:
files=(**/FILE_NAME*.CSV(ND.Om))
for file ($files); do
# Ваш код обработки файла здесь
echo "Обработка файла: $file"
done
В этом примере N
исключает отсутствующие, D
включает подкаталоги, и O
сортирует по времени модификации.
Заключение
Хотя команды find
и sort
позволяют вам получить список файлов в порядке их модификации, имейте в виду, что создание отдельной папки для прибывающих файлов может быть более надежным подходом. Вы можете перемещать файлы в окончательное местоположение после их обработки, что позволит вам лучше отслеживать новые файлы.
Надеюсь, это поможет вам успешно организовать обработку файлов в вашей системе!