1

Ранее я запускал dos2unix для каждого файла *.php на моем сервере с помощью этой команды:

find . -name '*.php' -type f -exec dos2unix --keepdate {} +

У всех файлов, обработанных dos2unix была изменена дата и время последнего изменения, но в родительском каталоге, содержащем такие файлы, дата и время последнего изменения все еще обновлялись до времени, когда я выполнил команду.

Как при помощи одного вкладыша рекурсивно дотронуться до каталогов, установив дату последнего изменения каталогов равной дате и времени последнего измененного файла в каталоге?

Из этого:

dir_a/               2013-05-13 14:05
   abc.php           2012-09-01 12:34
   def.php           2012-09-15 23:45
   dir_b/            2013-05-13 14:05
       uvw.php       2012-10-01 01:23
       xyz.php       2012-10-08 09:10

К этому:

dir_a/               2012-09-15 23:45
   abc.php           2012-09-01 12:34
   def.php           2012-09-15 23:45
   dir_b/            2012-10-08 09:10
       uvw.php       2012-10-01 01:23
       xyz.php       2012-10-08 09:10

Сервер работает на CentOS 5.6.

2 ответа2

2

Может быть, что-то вроде этого:

find . -type d -print0 | while read -r -d '' dir; do file="$(find "$dir" -maxdepth 1 -type f  -printf '%T+ %p\n' | sort -r | head -1 | cut -d' ' -f2-)";if [ -n "$file" ]; then touch "$dir" -mr "$file"; fi; done

Объяснение:

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

touch file1 -mr file2

Сначала мы должны найти подкаталоги:

find . -type d -print0 | while read -r -d '' dir; do echo "$dir"; done

В этом случае опция -exec будет слишком сложной, поэтому я использую метод while-read. Вы должны убедиться, что поток от find с NUL качестве разделителя записей, и укажите read для разделения на это (-d '').

Для поиска файлов с последней датой модификации я могу использовать:

find ./  -maxdepth 1 -type f  -printf '%T+ %p\n' | sort -r | head -1 | cut -d' ' -f2-

Сочетая это:

find . -mindepth 1  -type d -print0 | while read -r -d '' dir; do file="$(find "$dir" -maxdepth 1 -type f  -printf '%T+ %p\n' | sort -r | head -1 | cut -d' ' -f2-)";echo "$dir <- $file"; done

Наконец, добавление прикосновения:

find . -mindepth 1  -type d -print0 | while read -r -d '' dir; do file="$(find "$dir" -maxdepth 1 -type f  -printf '%T+ %p\n' | sort -r | head -1 | cut -d' ' -f2-)";touch "$dir" -mr "$file"; done

Я использую опцию -mindepth потому что я запустил эту команду из каталога, содержащего dir_a, у которого нет файла для чтения даты. Чтобы устранить эту проблему, я могу использовать if-else, чтобы убедиться, что я не пытаюсь прочитать время из несуществующего файла:

find . -type d -print0 | while read -r -d '' dir; do file="$(find "$dir" -maxdepth 1 -type f  -printf '%T+ %p\n' | sort -r | head -1 | cut -d' ' -f2-)";if [ -n "$file" ]; then touch "$dir" -mr "$file"; fi; done
1

Это должно сделать это:

find -mindepth 1 -type d -print0 | while IFS= read -r -d '' dir; do 
 time=$(
  find "$dir" -mindepth 1 -maxdepth 1 -type f -exec stat -c %Y {} \; | 
  sort -nk2 | tail -n 1
 ); touch -d @$time "$dir"; 
 done

ОБЪЯСНЕНИЕ:

  • find -mindepth 1 -type d | while IFS= read -r -d '' dir; do : перебрать все каталоги, кроме текущего (-mindepth 1). Используя while цикла с IFS= и флаг -r чтобы убедиться , что команда работает с именами каталогов , которые содержат пробелы или новые строки \n или другие странные символы. -d '' устанавливает разделитель на нулевой символ, чтобы он мог работать с опцией find -print0 .

  • find $dir -mindepth 1 -maxdepth 1 -type f -exec stat --printf="%Y\n" {} \; : Найти все файлы каждого каталога $dir и запустить stat который печатает дату их модификации в секундах с начала эпохи .

  • sort -nk2 | tail -n 1 : просто сортирует даты и сохраняет самые новые. Последние две части вместе дают время модификации самого нового файла, который сохраняется в переменной $time .

  • touch -d @$time $dir : здесь мы используем команду touch чтобы установить время модификации каждого каталога. @ Есть сказать touch , что мы повторно давая время в секундах с начала эпохи, это стандартный GNU Coreutils особенность .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .