Переміщення файлів за датою в інший каталог за допомогою 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 {} / ваш / цільовий / каталог \; ' замість '-принт 0 | xargs -0 cp -t / ваш / target / каталог 'працює так само добре, як проблеми з пробілами в іменах? (Також ОП хотіла перенести не копіювати )
Хаген фон Ейтцен

^^ Так. Обидва досягають однієї мети.
шивам

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

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

Мені подобається ваш пов'язаний сценарій; як не дивно, це було б дуже корисно пару місяців тому саме для цієї ж мети. Ну добре. Я навіть можу спробувати припинити використання cpio -H ustar...
roaima
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.