Переместить файлы из специально названных папок / переместить файлы на один уровень вверх
Целью является перемещение файлов из папки самого низкого уровня, резервное копирование одного каталога.
Это отлично работает, но перемещает файлы выше по иерархии папок.
find . -name '*.jpg' -type f -execdir mv '{}' ../ \;
Так что, если эти jpgs были размещены в папке под названием "фотографии", я хочу переместить их на один уровень, например)
../
Я попытался изменить параметр '*.jpg', чтобы включить папку, и попытался использовать папку вместо точки после файла. Также пробовал -maxdepth и -mindepth, но они не имели никакого эффекта.
РЕДАКТИРОВАТЬ: это для нескольких папок, т.е. он должен проходить через весь диск.
3 ответа
Переместить файлы из нижнего подкаталога на один уровень вверх
Приведенный ниже скрипт рекурсивно ищет в каталоге самый нижний подкаталог (= без подкаталогов) и перемещает все найденные файлы в папке (папках) на один уровень вверх, как об этом буквально спрашивается в разделе "Цель состоит в том, чтобы переместить файлы из папки самого низкого уровня" создайте резервную копию одного каталога:
#!/usr/bin/env python2
import shutil
import os
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for dr in dirs:
dr = root+"/"+dr
# find folders without subfolders (= lowest level)
if len(next(os.walk(dr))[1]) == 0:
# direct superior directory
up = dr[:dr.rfind("/")]
# move files from lowest level one level up
for f in os.listdir(dr):
shutil.move(dr+"/"+f, up+"/"+f)
Использовать:
- Скопируйте скрипт в пустой файл, сохраните его как
reorganize.py
Запустите его командой:
python /path/to/reorganize.py <directory_to_reorganize>
Если имя вашего каталога (для реорганизации) содержит пробелы, используйте кавычки:
python /path/to/reorganize.py '<directory_to_reorganize>'
РЕДАКТИРОВАТЬ
Как уже упоминалось в комментарии, с небольшими изменениями скрипт можно использовать только для перемещения файлов из имени папки на один уровень вверх. Самый эффективный способ - сделать это сразу после
for dr in dirs:
Тогда скрипт будет:
#!/usr/bin/env python3
import shutil
import os
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for dr in dirs:
if dr == "<folder_name>":
dr = root+"/"+dr
# direct superior directory
up = dr[:dr.rfind("/")]
# move files from lowest level one level up
for f in os.listdir(dr):
shutil.move(dr+"/"+f, up+"/"+f)
Если все ваши целевые файлы находятся в каталогах с именем photos
Вы могли бы сделать что-то вроде:
find . -type d -name photos -exec bash -c 'cd {} && mv *jpg ../' \;
Это будет искать имена каталогов photos
, а затем запустить оболочку bash, которая будет cd
в каждый из них и переместить все .jpg
файлы в родительский каталог.
Следующее переместит все .jpg
файлы в соответствующие родительские каталоги, если .jpg
файлы находятся только в каталоге с именем photos
(может быть несколько каталогов с именем photos
):
find . -type f -path '*/photos/*' -not -path '*/photos/*/*' -name '*.jpg' \
-execdir mv -i {} .. \;
-path '*/photos/*'
будет гарантировать, что путь будет содержать photos
но файлы могут быть только под photos
каталог (-not -path '*/photos/*/*'
).
Также обратите внимание, что если каталоги не путешествовать (не photos
) являются фиксированными и имеют меньшие числа или имеют определенные закономерности, тогда вас могут заинтересовать -prune
тоже.
Найдет самый низкий уровень в каждой ветви каталога и будет использовать его в качестве основы для поиска, а затем переместит "*.jpg" на один уровень вверх.
#!/bin/bash
treedir="."
mapfile -d '' < <(find "$treedir" -depth -type d -print0)
L=""
A=()
for D in "${MAPFILE[@]}"; do
[[ $L != $D/* ]] && A+=("$D"); L="$D"
done
for basedir in "${A[@]}"; do
find "$basedir" -name '*.jpg' -type f -execdir mv -i -t .. '{}' \;
done