Как скопировать все папки, которые содержат определенный файл

Я хочу сделать резервную копию только моих музыкальных папок FLAC. Файлы FLAC могут быть вложены в папки следующим образом:

AlbumName/
├── Files/
│   ├── someSong01.flac
│   ├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

Как скопировать и переместить все папки AlbumName с соответствующей структурой и содержимым, которые содержат где-то внутри хотя бы один файл FLAC (я предполагаю, что это достаточно сказать: музыка в формате FLAC)

РЕДАКТИРОВАТЬ: FLAC-файлы могут быть вложенными; поэтому я могу иметь:

AlbumName2/
├── someSong01.flac
├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
|   └── someCover02.jpg

И я хочу скопировать эти папки со всем их содержимым, а не только FLAC-файлами, и вставить в другой каталог.

Так что, если у меня есть

AlbumName3/
├── someSong01.mp3
├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
|   └── someHiddenSong.flac

и

AlbumName4/
├── Files/
│   ├── someSong01.mp3
│   ├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

, я хочу рекурсивно копировать в другой каталог AlbumName, AlbumName2 и AlbumName3, но не AlbumName4

РЕДАКТИРОВАТЬ: Ни один из ответов на самом деле не делал то, что я хочу, поэтому я в итоге использовал что-то вроде этого:

 find -mindepth 2 -name '*.flac' -exec dirname {} \; | awk -F "/" '{print $2}' | sort -u | while read -r dirname; do cp -r "$dirname" "backup/"; done

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

17
задан 19 May 2018 в 00:44

5 ответов

Можно использовать rsync, который копирует только файлы flac и сохраняет структуру каталогов:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • архив
  • v verbose
  • z compress во время передачи (может быть бесполезным копирование на тот же компьютер)
  • m обрезать пустые каталоги
  • первое включение включает в себя все каталоги
  • второе включение включает в себя файлы flac
  • последнее исключение исключает все остальные файлы
19
ответ дан 19 May 2018 в 00:44

привет, мой друг, ты можешь использовать

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
9
ответ дан 19 May 2018 в 00:44

Хорошие ответы

Я хочу добавить еще один способ, вы также можете использовать комбинацию find и cpio

find . -name "*.flac" -print0|cpio --null -pdm destination/

Объяснение:

GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules of precedence (see Operators), until the outcome is known (the left-hand side is false for AND operations, true for OR), at which point find moves on to the next file name.

GNU cpio is a tool for creating and extracting archives, or copying files from one place to another. It handles a number of cpio formats as well as reading and writing tar files.

Есть 3 режима cpio:

  • Режим копирования: In copy-out mode, cpio copies files into an archive. It reads a list of filenames, one per line, on the standard input, and writes the archive onto the standard output.

  • Режим копирования: In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • Режим копирования: In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.

Здесь мы используем режим копирования-пропуска.

  • Опции, используемые в вышеприведенной команде:

найти:

  • -name -> имя файла или используйте регулярное выражение вместо записи полного имени

cpio:

  • '- m, --preserve-модификация-time' Retain previous file modification times when creating files.
  • '- p, - pass-through' Run in copy-pass mode. see ``Copy-pass mode``.
  • '- d, --make-directoryies' Create leading directories where needed.'
  • --quiet' Не печатать количество скопированных блоков.

New options are the "-print0" available with GNU find, combined with the "--null" option of cpio. These two options act together to send file names between find and cpio, even if special characters are embedded in the file names.

Можно также использовать rsync или написать сценарий оболочки для поиска и копирования файлов со структурой каталогов.

Для объяснения Rsync, пожалуйста, посмотрите на ответы выше.

5
ответ дан 19 May 2018 в 00:44

Ответ 1: Вы также можете использовать команду find для того же.

mkdir newDir && find AlbumName/ -iname "*.flac" -exec cp --parents "{}" newDir/ \;

Объяснение:

mkdir создает новый каталог. Команда find находит *.flac файлы, расположенные в папке AlbumName. Команда exec выполняет команду cp для каждого имени файла, которое вернуло find.

Ответ 2: Вы также можете использовать команду find вместе с xargs

mkdir newDir && find AlbumName/ -iname "*.flac" | xargs -I{} cp --parents {} newDir/

Дополнительная информация: find , xargs

4
ответ дан 19 May 2018 в 00:44

Просто пришлось решить ту же проблему для моей музыкальной библиотеки и решить ее, используя следующий адаптированный скрипт. Я не полностью разработал его с переменными, т. Е. Собираюсь использовать его только один раз:).

Сценарий перемещает каждый каталог, содержащий файлы flac, включая все остальные файлы и подкаталоги, в новое место с помощью rsync. rsync позволяет вам возобновить выполнение сценария, если он остановился во время процесса.

Моя структура библиотеки:

library
|-artist
  |- album 1 (mp3)
  |- album 2 (flac)

Новая структура библиотеки:

library
|-artist
  |- album 1 (mp3)

library-lossless
|-artist
  |- album 2 (flac)

(1) запустить следующий сценарий оболочки в месте назначения SOURCE (замените TARGET на соответствующий каталог по вашему выбору - я просто использовал абсолютный путь)

строка 1: найти все каталоги, содержащие файлы flac и pipe (|), в сортировку
строка 2: удалить дубликаты с помощью sort и pipe этот список в цикле do
строка 3: для каждого каталога do
строка 4: показать каталог в процессе
строка 5: rsync в целевой каталог плюс удалить источник и сохранить структуру (-R) в целевом местоположении
строка 6: удалить пустой каталог (поскольку rsync удаляет только файлы)

find . -type f -name \*.flac -printf "%h\n" | 
sort -u | 
while read -r dirname; do
    echo $dirname
    rsync -azvm -R --remove-source-files "${dirname}" TARGET
    find "${dirname}" -type d -delete
done

(2) после успешного выполнения В сценарии (1) вы можете выполнить следующую команду в исходном каталоге

find . -depth -type d -empty -delete

Эта команда удаляет все пустые каталоги, не удаленные в сценарии. То есть Каталоги "Artist", где все подпапки / альбомы содержат файлы flac.

0
ответ дан 19 May 2018 в 00:44

Другие вопросы по тегам:

Похожие вопросы: