Переместить файлы из специально названных папок / переместить файлы на один уровень вверх

Целью является перемещение файлов из папки самого низкого уровня, резервное копирование одного каталога.

Это отлично работает, но перемещает файлы выше по иерархии папок.

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)

Использовать:

  1. Скопируйте скрипт в пустой файл, сохраните его как reorganize.py
  2. Запустите его командой:

    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
Другие вопросы по тегам