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

17

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

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

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

EDIT: Файлы 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

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

EDIT: Ни один из ответов действительно не делал то, что я хочу, поэтому в итоге я использовал что-то вроде этого:

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

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

    
задан fricadelle 21.12.2017 в 08:08
источник

5 ответов

18

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

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

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

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
    
ответ дан amir.m ghazanfari 21.12.2017 в 08:25
5

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

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

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

Explanation:

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.

There are 3 cpio modes:

  • Copy-out mode: 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.

  • Copy-in mode: In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • Copy-pass mode: 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.

Here, we are using Copy-pass mode.

  • Параметры, используемые в следующей команде:

find:

  • -name -> filename or use regex instead of writing full-name

cpio:

  • '-m, --preserve-modification-time' Retain previous file modification times when creating files.
  • '-p,--pass-through' Run in copy-pass mode. see ''Copy-pass mode''.
  • '-d, --make-directories' Create leading directories where needed.'
  • --quiet' Do not print the number of blocks copied.'

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 или написать сценарий оболочки для поиска и копирования файлов со структурой каталогов.

For Rsync explanation, Please have a look at above answers.

    
ответ дан Neeraj Pal 21.12.2017 в 09:07
4

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

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

Explaination:

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

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

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

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

    
ответ дан mf_starboi_8041 21.12.2017 в 08:45
0

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

Сценарий перемещает каждый каталог, содержащий файлы 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: удалить дубликаты с сортировкой и трубкой, которые перечислены в цикле do

строка 3: для каждого каталога выполните строка 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.

    
ответ дан wundabua 25.12.2017 в 19:55