Переместите файлы по дате в другой каталог, используя CLI


9

У меня есть большое количество фотографий со старого жесткого диска, которые я пытаюсь организовать. Если я запускаю ls -l, я замечаю, что все эти файлы имеют дату создания 2012 или ранее. В идеале я хотел бы перенести их на второй жесткий диск моего компьютера, который не настроен для автоматического монтирования. Предпочтительно, я мог бы сделать все это как пакет с некоторыми командами, связанными вместе. Пока у меня есть, ls -l | grep -i 2012который выкладывает только файлы с 2012 года на дату, указанную ls -l. Теперь хитрость заключается в том, чтобы cpпереместить все эти файлы в новый каталог. Я не уверен, куда идти дальше с этим, потому что каждый файл должен быть скопирован. Каким будет мой следующий набор команд?

Ответы:


13

Не используйте ls. Не рекомендуется использовать в таких случаях. Кроме того, использование grepдля фильтрации по дате не является хорошей идеей. Ваше имя файла может содержать 2012строку, даже если она не была изменена в 2012 году.

Используйте findкоманду и передайте ее вывод.

find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory 

Вот,

-newermt 20120101  ==>  File's modified date should be newer than 01 Jan 2012
-not               ==>  reverses the following condition. Hence file should be older than 01 Jan 2013
-print0 and -0     ==>  Use this options so that the command doesn't fail when filenames contain spaces 

1
Не будет `-exec mv {} / your / target / directory \; ' вместо '-принт 0 | xargs -0 cp -t / your / target / directory 'работает так же хорошо в отношении проблем с пробелами в именах? (Также ОП хотел переместить не копировать )
Хаген фон Айцен

^^ Да. Оба достигают одной и той же цели.
Шивамс

4

Если у вас есть новые файлы на старом диске, которые вы хотите игнорировать, я бы сделал это так

  1. Создайте временный файл маркера с измененной датой, который отделяет нужные мне файлы от тех, которые я не делаю
  2. Скопируйте файлы старше файла маркера в новое место

Вот примеры команд для этого, которые предполагают, что вы хотите сохранить любую иерархию каталогов со старого диска в новом ( cpioэто команда копирования, похожая на tarили pax):

touch -t 201201010000 /tmp/marker    # YYYYMMDDhhmm == Jan 1st, 2012
cd /path/to/old/disk
find . -type f \! -newer /tmp/marker -print0 | cpio -pmd0 /path/to/new/disk

2

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

Я пишу этот новый сценарий на основе первого ответа этой проблемы:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. запишите этот скрипт в файл с именем copy.shв вашем старом каталоге.

  2. замените /your/new/directoryпуть к вашему новому каталогу

  3. сделать этот файл исполняемым с chmod +x copy.sh

  4. затем выполните этот файл ./copy.sh


1
Вы можете добавить обработку исключений, поэтому сценарий не двигается себя в 2015каталог.
G-Man говорит: «Восстановите Монику»

1

Вы, вероятно, должны использовать пакетный инструмент для пакетных операций. Это обычно влечет за собой чтение / запись всех записей в одном потоке, а не, например, вызов отдельного cpпроцесса для каждого скопированного файла.

Здесь уже cpioнаписан ответ, который, учитывая только варианты, уже предоставленные вам, скорее всего, я бы выбрал. Тем не менее, cpioформат был улучшен и свернут в стандартизированный paxформат архива с его расцвета. То же самое относится и к tar.

Строго POSIX - paxвряд ли предоставит какие-либо опции для прямой фильтрации членов архива в зависимости от времени изменения файла - хотя стандарт определяет %Tмодификатор формата в режиме списка. Тем не менее, наиболее распространенная paxиз известных мне реализаций - версия BSD, поддерживаемая mirabilos, - действительно расширяет ее до напрямую доступного CLI-коммутатора.

Например, чтобы скопировать только файлы в дереве с корнем в ./котором последнего изменения , прежде чем ccyymmddHHMMк /target/dirвы могли бы сделать:

pax -rwT,201301010000 ./ /target/dir

Чтобы не возвращаться в дочерние каталоги, вы можете сделать следующее:

pax -rwdT,201301010000 ./* /target/dir

Смотрите manстраницу для получения дополнительной информации.


Я думаю, что я действительно должен учиться pax, но tarи cpioдо сих пор хорошо меня выдерживает. +1
роайма

@roaima - строго говоря, хотя существует фактический paxформат архива (который является расширением формата ustar ) , pax утилита POSIX-spec может читать / записывать форматы cpio, pax и ustar. Поскольку все три типа архива в основном сводятся к разным средствам кодирования метаданных для многих файлов вместе с фактическими данными указанных файлов в единый поток, на самом деле это не слишком много. Однажды я написал shitar- это было всего несколько строк shell-скрипта для - в основном dd- tarразработчиков блоков на лету на основе спецификации POSIX.
mikeserv

Мне нравится ваш связанный скрипт; странно, что это было бы очень полезно пару месяцев назад для той же цели. Ну что ж. Я мог бы даже попытаться прекратить использовать cpio -H ustar...
Ройма
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.