Копіювання всіх файлів у підкаталоги та перейменування замість перезапису


2

У мене є декілька зображень у підкаталогах іншої директорії, яку я хотів би скопіювати в один каталог, щоб всі зображення знаходилися в одному місці.

Після декількох пошуків я знайшов, а потім змінив деякі речі, щоб створити цю команду:

find . -name "z*.jpg" -exec cp '{}' ~/Extracted/ \;

Це, здавалося б, працювало, але я виявив, що зображення з такою ж назвою будуть перезаписані, тому я зробив це

find . -name "z*.jpg" -exec cp -n '{}' ~/Extracted/ \;

Але тепер зображення з однаковою назвою просто ігноруються.

Чи можу я це зробити так, щоб кожен образ копіювався, а зображення з такою ж назвою перейменовувалися?

Відповіді:


4

GNU cp(1) має варіант резервного копіювання:

cp --backup SOURCE [SOURCE...] [DESTINATION]

Це має наступні ефекти, якими можна керувати за допомогою інших варіантів, як описано в розділі ручної сторінки з cp(1):

--backup[=CONTROL]
          make a backup of each existing destination file

-b     like --backup but does not accept an argument

-S, --suffix=SUFFIX
          override the usual backup suffix

Суфікс резервного копіювання є ~, якщо не встановлено значення --suffix або SIMPLE_BACKUP_SUFFIX. Можна вибрати метод контролю версій   через --backup або через VERSION_CONTROL навколишнє середовище   змінної. Ось значення:

  • none, off: ніколи не створюйте резервні копії (навіть якщо --backup дано)
  • numbered, t: зробити пронумеровані резервні копії
  • existing, nil: пронумеровані, якщо існують пронумеровані резервні копії, просто інакше
  • simple, never: завжди робити прості резервні копії

Приклад

cp --backup=existing --suffix=.orig ~/Music/* ~/Videos

Це скопіює всі файли ~/Music до ~/Videos. Якщо файл з тим же ім'ям існує на місці призначення, його перейменовують шляхом додавання .orig на ім'я резервної копії. Якщо файл з такою ж назвою, що й резервна копія, існує, резервна копія замість цього перейменовується .1 і, якщо це також існує, .2 і так далі. Тільки тоді вихідний файл буде скопійовано до місця призначення.

Якщо потрібно скопіювати файли в підкаталоги, рекурсивно використовуйте -R:

cp -R --backup=existing --suffix=.orig ~/Music ~/Videos

Хоча інша відповідь вирішила мою проблему, це рішення набагато простіше здійснити. Це може бути корисним у майбутньому. Дякую!

2

Ваша проблема насправді знайти cp варіант, який створює цільовий файл під іншим ім'ям, якщо він вже існує. Мені невідомо про такий інструмент, однак реалізувати себе не важко:

#!/bin/bash
cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"

Цей скрипт викликає cp знову в разі невдачі, додаючи контрольну суму до імені файлу. Порушення: якщо з'являється третій файл з тим же ім'ям, він перезапише другий файл якщо вони ідентичні .

Враховуючи, що наведений вище сценарій викликається saveCopy і зберігаються у батьківському робочому каталозі наступні роботи:

$ find . -name 'z*.jpg' -exec ./saveCopy {} /tmp/Extracted/ \;
./a/z1.jpg -> /tmp/Extracted/z1.jpg
./a/z2.jpg -> /tmp/Extracted/z2.jpg
./a/z3.jpg -> /tmp/Extracted/z3.jpg
/tmp/Extracted/z3.jpg not overwritten
./b/z3.jpg -> /tmp/Extracted//z3.jpg~d41d8cd98f00b204e9800998ecf8427e
./b/z4.jpg -> /tmp/Extracted/z4.jpg

Майте на увазі, що сценарій працює тільки для одного вхідного файлу, і якщо цільовий каталог - це каталог! Безумовно, можна покращити ;-)


Приємно, +1. Чому було б недоліком перезапису ідентичні файлів?
— terdon

@terdon недолік насправді більше, що ви все ще в кінцевому підсумку з 2 копії ідентичного файлу, тому що перша копія не має хеш додається. Це не послідовно. Однак, я просто хотів зберегти приклад невеликий, якщо хочеться використовувати щось подібне на регулярній основі, слід подумати про трохи складнішому рішенні.
— barbaz

Ви можете зробити це більш узгодженим, просто пропускаючи копіювання вихідного файлу, використовуючи тільки код після ||: cp -vn "$ 1" "$ 2" / "$ {1 ## * /}" ~ "$ (md5sum" $ 1 "| cut -f1 -d '') - проблема полягає в тому, що розширення файлу переплутано з md5sum
— Robin Manoli
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.