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


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.