Пакетное изменение даты создания файла в терминале Mac OS на заданное время

avatar
Peter Walker
9 августа 2021 в 06:48
269
1
0

Краткая предыстория

Я купил роутер и настраивал его. Казалось бы, когда я подключил свой NAS, маршрутизатор еще не был настроен, поэтому время «создания» всех присутствующих файлов было перенесено примерно на 20 лет вперед (т. е. маршрутизатор начал с предположения, что год был 2000 г., когда это было в конце 2020 г.). В любом случае, у меня есть куча файлов, которые находятся в будущем на 10 с лишним лет.

Цель

Используя терминал Mac OSX (который я все еще настроил для использования оболочки bash и не zsh), я хочу динамически изменять файлы с неправильными датами создания, чтобы удалить заданное количество времени.

Текущий прогресс

Чтение другого ответа SO говорит мне, что следующее изменит дату создания файла.

touch -t YYYYMMDDhhmm THE_FILE

Прочитав несколько справочных страниц и ответы на другой вопрос SO, я получил следующую команду для поиска всех файлов (в моем текущем каталоге) с проблемной датой.

find . -type f -newermt '1/1/2025 00:00:00'

Я также использовал третий ответ SO, чтобы выполнить некоторую отладку, чтобы убедиться, что моя математика дат была правильной.

date -r "$(expr $(stat -f %c THE_FILE) - 661361702)" +%Y%m%d%H%M

В моем случае 661361702 было определено как "20 лет 11 месяцев 15 дней" в секундах, продолжительность времени с 01.01.2000 00:00:00 до дня, когда я настраивал маршрутизатор и запутался даты.

Для набора файлов, соответствующих моим критериям с find, я хочу использовать touch для изменения даты создания, рассчитанной на основе результатов stat в файле с вычетом заданного количества секунд с текущей даты создания каждого файла.

Я пытаюсь сшить все это вместе и не знаю, как правильно использовать параметр -exec команды find, чтобы правильно вложить все эти команды в одну строку.

Источник

Ответы (1)

avatar
Renaud Pacalet
9 августа 2021 в 06:57
2

Цикл bash, вместо того чтобы пытаться уместить все это в действие exec действия find, возможно, облегчит кодирование вашего скрипта:

find . -type f -newermt '1/1/2025 00:00:00' -print0 | \
while IFS= read -r -d '' f; do
    s=$(stat -f %c "$f")
    (( s -= 661361702 ))
    d=$(date -r "$s" +%Y%m%d%H%M)
    touch -t "$d" "$f"
done

Примечание: в приведенном выше решении используется параметр -print0 для find и пустой разделитель read (-d '') для разделения найденных имен файлов символом NUL вместо пробела по умолчанию. Это надежно и будет работать, даже если у вас есть имена файлов с символами новой строки, табуляцией, пробелами...