Я рекомендую:
find /source/ -type f -newermt '18 dec 2020' -exec cp -t /target/ {} +
Это рекомендуется копировать только файлы без структуры каталогов, но мне нужны файлы с его родительским каталогом.
Во-вторых, почему дата файлов меняется при их копировании? Можно ли не менять дату изменения файла при их копировании?
Вы можете сделать это с помощью find
и либо cp
с -parents
, что требует .. /target, чтобы существовать, хотя.
(builtin cd source; find -type f \
-newermt '18 dec 2020' -exec cp --parents -at ../target {} +)
Второй вариант использует cpio
, который является более производительным. В то время как в предыдущем примере используется cd
для удаления начальной точки перед копированием, мы достигаем этого с помощью директивы -printf
и cpio -D
. И для этого не потребуется существующий целевой объект перед копированием.
find source/ -mindepth 1 -depth -type f \
-newermt '18 dec 2020' -printf %P\\0 | cpio -0 -pvdm -D source/ target
Существует опция --preserve=all
для cp
; см. man cp
.
Но я рекомендую использовать rsync
вместо cp
; он гораздо более универсален, и его легко заставить сохранять временные метки и копировать только новые файлы. У него есть некоторая кривая обучения со всеми этими опциями, которые он поддерживает, но это стоит того, чтобы погрузиться в это.
Обычный сценарий использования выглядит примерно так:
rsync -n -av /some/where/sourcedir .
Это рекурсивно копирует sourcedir в текущий каталог как подкаталог sourcedir/
. Это не коснется файлов, которые уже находятся там и имеют ту же временную метку / содержимое. Опция -n
означает, что это просто пробный запуск, чтобы вы могли посмотреть, что он будет делать (вместе с -v
для verbose). Когда вы будете довольны тем, что он будет делать, запустите его без -n
:
rsync -av /some/where/sourcedir .
Вы можете вызывать его несколько раз; если он больше ничего не делает, значит, все готово.
Вы также можете удалить файлы, которые больше не находятся в дереве исходного каталога, с помощью --delete
:
rsync -av --delete /some/where/sourcedir .
Если вы добавите косую черту к исходному пути, это не создаст подкаталог sourcedir/
на месте назначения, а скопирует его прямо в этот подкаталог. Вместе с --delete
, он создает 1:1 копию этого дерева в текущем каталоге, также удаляя все, чего нет в исходном поддереве:
rsync -av --delete /some/where/sourcedir/ .
Снова добавьте -n
, чтобы увидеть, что сделает. Вообще, я настоятельно рекомендую всегда использовать -n
, чтобы убедиться, что он сделает то, что вы хотите.
Существует масса других опций (например, --exclude=
); смотрите man rsync
.