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


17

Я хочу сделать резервную копию только моих музыкальных папок 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

Я хочу рекурсивно cp в другой каталог 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, извлекаю корневую папку с помощью awk, удаляю дубликаты и делаю что хочу


резервное копирование, где, каков ваш пункт назначения?
Джордж Удосен

Нужно ли копировать только файлы flac или целые папки, в которых есть хотя бы один файл flac?
никто не

@nobody folder: « Как мне скопировать и переместить все папки AlbumName с соответствующей структурой и содержимым, которые содержат где-то внутри хотя бы один FLAC-файл »
terdon

Ответы:


19

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

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • архив
  • в подробности
  • Сжатие во время переноса (может быть бесполезно при копировании на тот же компьютер)
  • м чернослив пустых пап
  • Первое включение включает в себя все каталоги
  • второй включает в себя файлы FLAC
  • последнее исключение исключает все остальные файлы

В самом деле? Я понимаю, он хочет сохранить структуру каталогов. Он говорит: «Как мне скопировать и переместить все папки AlbumName с их соответствующей структурой и содержанием ...».
никто не

2
А ну понятно. Я не уверена. Нужно ли копировать только файлы flac или целые папки, в которых есть хотя бы один файл flac?
никто не

Вопрос отредактирован и теперь он более подробно объясняет, чего хочет Фрикадель. Принимая во внимание, что все содержимое должно быть скопировано, если есть файл flac, мой ответ неверен, поскольку он копирует только файлы flac. Однако это все еще может быть полезно для некоторых других целей.
никто не

9

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

mkdir newdirectory
cp -r --parents */*.flac newdirectory/

2
Ницца никогда не использовалась --parentsраньше!
Джордж Удосен

4
Пожалуйста, объясните это */*.flac! Будет cp -r --parents AlbumName/ newdirectory/не хватать?
Джордж Удосен

3
Исходя из вопроса, похоже, что флаки могут быть или не быть во вложенных каталогах, поэтому я рекомендую включить globstar ( shopt -s globstar), а затем использовать **/*.flacдля glob. Двойная звезда будет соответствовать нулю или более каталогов.
wjandrea

Вы абсолютно правы, wjandrea, позвольте мне отредактировать мой вопрос, чтобы все поняли
fricadelle

5

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

Я хочу добавить еще один способ, вы также можете использовать комбинацию 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.

Здесь мы используем режим Copy-pass.

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

находить:

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

CPIO:

  • '-m, --preserve-модификация-время' Retain previous file modification times when creating files.
  • «-P, - сквозная» Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --make-directory' 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, пожалуйста, посмотрите на ответы выше.


2
Вы можете улучшить свой ответ, включив пояснения к командам и вариантам, которые вы предлагаете. - Из обзора
Дж.

@ дезертир да, верно. Спасибо за ваше идеальное предложение.
bsdboy

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


1
find | xargsбудет ломаться на имена файлов с пробелами, вместо этого используйте find -print0 | xargs -0.
десерт

Я попытался с 1 2.flacфайлом, который имеет место в имени файла. Можете ли вы дать мне знать имя файла, в котором происходит find | xargsсбой?
mf_starboi_8041

см. например здесь
десерт

Я не знаю, но я могу скопировать файл с длинным именем, в котором есть место, без использованияfind -print0 | xargs -0
mf_starboi_8041

Попробуй touch "a space" && find . | xargs ls.
десерт

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.