Хорошо, таким образом, у меня есть очень крупная библиотека iTunes и недавно решенный, чтобы отсортировать его и организовать его намного более опрятным способом, чем просто бросок всей моей музыки в папке и надежде на лучшее. Таким образом, после многих часов движущихся файлов в и или каталоги и ожидающий iTunes, чтобы сделать независимо от того, что это - iTunes, делает, так или иначе я закончил с несколькими недостающими песнями. Если это было 1 или 2, поэтому что, я могу найти ими один. Но я пропускаю немногим более, чем 30 000, таким образом, я не слишком увлечен идеей искать их вручную.
Таким образом, мой вопрос, "Существует ли путь ко мне к в среде Linux, найдите все файлы, которые находятся в 1 каталоге, которые не находятся в другом и затем перемещают их?"
Моя структура папок немного походит на это:
Родительский каталог (внешний жесткий диск)
(Я действительно плох в списках в этих questions^), Поэтому, в чем я нуждаюсь, должен переместить что-либо, что находится в каталоге "Missing Files", который не находится в "Папке iTunes"
Спасибо за любую справку заранее парни, я действительно ценю его.
Примечание: Я только хочу переместить mp3 файлы от папок, не самих папок.
Принятие Вас имеет структуру каталогов как:
music
|- source
|- foobar
|- spamegg
|- ...
|- dest
и необходимо переместить все .mp3
файлы под любым уровнем подкаталогов music/source/
кому: music/dest/
только если файл, не уже существующий в music/dest/
.
Если это так, выполняя все команды ниже от music/
каталог:
Создайте массив, содержащий все .mp3
файлы под music/source
, рекурсивная операция:
shopt -s globstar ## Enables recursive search
source_files=( source/**/*.mp3 )
Сделайте то же с music/dest/
каталог и снимает изоляцию с части каталога от имен файлов:
dest_files=( dest/**/*.mp3 )
dest_files=( ${dest_files[@]} )
Выполните итерации по исходным файлам и проверке, если файл уже существует в месте назначения, если нет mv
файл к music/dest/
:
for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
echo mv -i "$i" dest/; done
echo
для doi9ng, который просто удаляет пробный прогон, если удовлетворено, echo
:
for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
mv -i "$i" dest/; done
Форма в виде сценария:
#!/usr/bin/env bash
shopt -s globstar
source_files=( source/**/*.mp3 )
dest_files=( dest/**/*.mp3 )
dest_files=( ${dest_files[@]} )
for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
mv -i "$i" dest/; done
Можно, очевидно, использовать полные пути, изменить соответствующие тракты для встречи Вас потребность.
Протесты:
Весь источник и место назначения .mp3
файлы помещаются в массивы, бит потребностей дополнительной памяти, не должна быть проблема в современных системах
Тест членства занимает время, снова не должно быть примечательным в современных системах
Пример:
music$ tree
.
├── dest
│ ├── 1.mp3
│ ├── 2.mp3
│ ├── 3.mp3
│ ├── 7.mp3
│ ├── 8.mp3
│ └── 9.mp3
└── source
├── bar
│ ├── 10.mp3
│ ├── 6.mp3
│ ├── 7.mp3
│ ├── 8.mp3
│ └── 9.mp3
└── foo
├── 1.mp3
├── 2.mp3
├── 3.mp3
├── 4.mp3
└── 5.mp3
music$ shopt -s globstar
music$ source_files=( source/**/*.mp3 )
music$ dest_files=( dest/**/*.mp3 )
music$ dest_files=( ${dest_files[@]} )
music$ for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && echo mv "$i" dest/; done
mv source/bar/10.mp3 dest/
mv source/bar/6.mp3 dest/
mv source/foo/4.mp3 dest/
mv source/foo/5.mp3 dest/
music$ for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && mv "$i" dest/; done
music$ tree
.
├── dest
│ ├── 10.mp3
│ ├── 1.mp3
│ ├── 2.mp3
│ ├── 3.mp3
│ ├── 4.mp3
│ ├── 5.mp3
│ ├── 6.mp3
│ ├── 7.mp3
│ ├── 8.mp3
│ └── 9.mp3
└── source
├── bar
│ ├── 7.mp3
│ ├── 8.mp3
│ └── 9.mp3
└── foo
├── 1.mp3
├── 2.mp3
└── 3.mp3