Automator - найти и переместить самый последний файл в отфильтрованном списке - PullRequest
0 голосов
/ 19 января 2020

Я пытаюсь использовать Automator, чтобы

  1. получить отфильтрованный список файлов в папке, которые старше 30 дней (хорошо)
  2. переместить самый последний из те (если они есть) в существующую подпапку
  3. tra sh остальные.

Шаг 1 достаточно прост, но я не смог найти способ выполнить шаг 2 - выбрать и переместить самый последний из отфильтрованных наборов.

Результат будет таким: если рабочий процесс запланирован один раз в месяц, тогда подпапка будет содержать один файл в месяц, а родительская папка будет содержать только файлы моложе 31 дня

Is Есть ли способ сделать это?

ОБНОВЛЕНИЕ Я попытался добавить сценарий оболочки в рабочий процесс автоматизатора

fn=$(ls -t | head -n1)
mv -f -- "$fn" ./<subdirectory>/

Но у меня проблемы с путем во второй строке.

1 Ответ

1 голос
/ 20 января 2020

ls -t | head -n1 это хорошо, но будьте осторожны; если subdir является самым последним измененным, он займет первый слот, что не только приведет к попытке переместить этот dir в себя (недопустимо, и это может быть вашей проблемой «с путем во второй строке»), но потенциально удаляя остальные файлы, включая тот, который вы хотите сохранить. Есть много способов отфильтровать любые каталоги; с моей головы ты мог бы ls -tp | grep -v '/$' | head -n1. Обратите внимание, что добавление файла в каталог влияет на эти каталоги mtime (время последнего изменения) в posix.

Удалить все файлы легко, как только вы удалите файл, который хотите сохранить, просто rm *. Обратите внимание, что это не приведет к удалению каталогов (если вы не указали -r), что, как мне кажется, является тем, что вам нужно, поскольку, похоже, вы перемещаете файл, который хотите сохранить, в подкаталог того места, где он был.

Возможно, вы захотите добавить также перехват ошибок, поэтому, если шаг завершится неудачей, последующие шаги не удаляют файлы, которые вы не хотите удалять. Я не использую automator, но это должно работать до тех пор, пока вы используете реальные bash: (включая другие планировщики, такие как cron, если вы сначала попадете в правильный рабочий каталог)

mv -- "$(ls -tp | grep -v '/$' | head -n1)" subdirectory/ && rm *

&& значит делать то, что следует, только если преуспевает то, что предшествует. Добавление ./ в начало файла назначения ничего не дает, хотя сохранение / в конце предотвращает создание нового файла с именем «subdirectory», если он еще не существует. Кроме того, я почти уверен, что «<>» в отправленном вами фрагменте кода помечает его как отличающийся от вашего фактического кода, но на всякий случай: обратите внимание, что подкаталог, как бы он ни вызывался, может нуждаться в специальной обработке, если он на самом деле содержит эти символы.

Редактировать:

Я только что заметил в вопросе ограничение "получить отфильтрованный список файлов в папке, которые более 30 дней старый». Итак, небольшое изменение: (используйте find для сравнения времени)

mv -- "$(find -maxdepth 1 -type f -mtime +30 -printf '%T@ %f\n' | sort -rn | head -n1 | cut -d\  -f2-)" subdirectory/ && find -maxdepth 1 -type f -mtime +30 -delete

Объяснение: найти в текущем каталоге (не подкаталогах, поэтому maxdepth 1) файлы (не каталоги, типа f), имеющие mtime не менее 30 дней в прошлом (-mtime +30) и выведите время изменения и имя (% T @% f); отсортировать, как если бы это было число (-n) в обратном порядке (-r); взять только первое (голова -n1); распакуйте имя файла (второе + разделенное пробелами поле) и переместите его в подкаталог. В случае успеха удалите все, что соответствует тем же критериям поиска, что и раньше.

Я не поместил бы файлы в переменную окружения, если диск / очень / медленный и не кэширован. Время, потраченное на фильтрацию имени файла, которое вы переместили, вероятно, потребует больше усилий, чем запрос диска, если только у вас нет безумного количества файлов, в этом случае они могут не помещаться в разделе среды.

Редактировать 2 : Камилчук прав. Использование null прекращено, так как null (единственный символ) недопустим в именах файлов:

find -maxdepth 1 -type f -mtime +30 -printf '%T %f\0' | sort -z -t' ' -r -n -s -k1 | head -z -n1 | cut -z -d' ' -f2- | xargs -0 -I{} mv {} subdirectory/ && find -maxdepth 1 -type f -mtime +30 -delete
...