Linux – Копирование файлов из нескольких вложенных папок с одинаковыми именами в одну папку

Вопрос или проблема

Мне нужна помощь в копировании большого количества файлов. Позвольте мне объяснить проблему.

ИСТОЧНИКОВАЯ СТРУКТУРА находится в /home/user/ToddCrimson/Pictures/iPhone-Media/ (В ней есть JPG, PNG, MOV и т. д., поэтому мне нужен скрипт, который сначала переместит JPG, затем я изменю поиск на MOV и поменяю папку назначения)

100APPLE
    IMG_0001.JPG - Время-Штамп-A
    IMG_0002.jpg - Время-Штамп-B
    IMG_0003.jpg - Время-Штамп-C
    IMG_0004.MOV - Время-Штамп-G
101APPLE
    IMG_0001.jpg - Время-Штамп-D
    IMG_0002.jpg - Время-Штамп-E
    IMG_0003.jpg - Время-Штамп-F
    IMG_0004.MOV - Время-Штамп-H
102APPLE
    IMG_0001.jpg - Время-Штамп-X
    IMG_0002.jpg - Время-Штамп-Y
    IMG_0003.jpg - Время-Штамп-Z
    IMG_0004.MOV - Время-Штамп-I
xxxAPPLE
    

СТРУКТУРА НАЗНАЧЕНИЯ находится в /home/user/ToddCrimson/Pictures/ (Я буду запускать скрипт для JPG, для PNG, для MOV и т. д., но сохраняя оригинальные временные метки)

Все_JPG
    Pic-00000001.jpg - Время-Штамп-A
    Pic-00000002.jpg - Время-Штамп-B
    Pic-00000003.jpg - Время-Штамп-C
    Pic-00000004.jpg - Время-Штамп-D
    Pic-00000005.jpg - Время-Штамп-E
    Pic-00000006.jpg - Время-Штамп-F
    -
    -
    -        -
    Pic-21897563.jpg - Время-Штамп-Z
    
Все_MOV
    Mov-00000001.MOV - Время-Штамп-G
    Mov-00000002.MOV - Время-Штамп-H
    -
    -
    -
    Mov-32188462.MOV - Время-Штамп-XX
    

Я пробовал различные комбинации RSYNC и CP, но, кажется, продолжаю терпеть неудачи. Есть ли помощь с точной командой, которую я могу выполнить?

Я хотел бы скопировать все тысячи JPG. Чтобы у них были все последовательные имена или хотя бы уникальные имена, но необходимо сохранить оригинальную временную метку.

Я на Debian 12. Могу сделать это через терминал или если существует GUI программа?

Итерируйте по всем директориям. В каждой директории итерируйте по файлам. Сохраняйте последовательный счетчик для целевых имен файлов.

#!/bin/bash
k=1
t="Однодиректория"

for d in Dir*
do
    for f in "$d"/*
    do
        x="${f##*.}"
        echo cp -p "$f" "$t/$(printf "Pic-%08d.%s" "$k" "$x")"
        ((k++))
    done
done

Если целевая директория находится на той же файловой системе, что и исходные директории, вы можете использовать ln вместо cp -p. Как вы могли бы ожидать, уберите echo перед cp, чтобы включить выполнение.

Если у вас слишком много файлов для * подстановочных знаков, возможно выполнить это иначе, но это более сложный метод и требует временного файла для хранения значения $k между циклами:

#!/bin/bash
k=1
t="Однодиректория"

echo "$k" >.k
find -maxdepth 1 -type d -name 'Dir*' -print0 |
    sort -z |
    while IFS= read -r -d '' d
    do
        find "$d" -maxdepth 1 -type f -print0 |
            sort -z |
            (
                k="$(cat .k 2>/dev/null)"
                while IFS= read -r -d '' f
                do
                    x="${f##*.}"
                    echo cp -p "$f" "$t/$(printf "Pic-%08d.%s" "$k" "$x")"
                    ((k++))
                done
                echo "$k" >.k
            )
    done
rm -f .k

Ответ или решение

Конечно! Ниже приведено решение задачи копирования файлов с одинаковыми именами из нескольких вложенных папок в одну папку с сохранением оригинальных временных меток и уникальными именами.

Шаги решения:

  1. Создайте целевую папку. Ваша целевая директория должна быть создана заранее. Например, мы будем использовать All_JPG для JPEG-файлов и All_MOV для MOV-файлов.

  2. Создайте bash-скрипт. Этот скрипт будет перебирать все подкаталоги и копировать файлы с корректным переименованием.

Пример скрипта для копирования JPG-файлов:

#!/bin/bash

# Значение счетчика и целевая директория
k=1
target_directory="/home/user/ToddCrimson/Pictures/All_JPG"

# Убедитесь, что целевая директория существует
mkdir -p "$target_directory"

# Перебираем все поддиректории и файлы
for dir in /home/user/ToddCrimson/Pictures/iPhone-Media/*; do
    if [[ -d $dir ]]; then  # только если это директория
        for file in "$dir"/*.jpg; do
            # Проверяем, существует ли файл
            if [[ -f $file ]]; then
                # Копируем файл с сохранением временной метки и переименованием
                cp -p "$file" "$target_directory/Pic-$(printf "%08d" "$k").jpg"
                ((k++))
            fi
        done
    fi
done

Пример скрипта для копирования MOV-файлов:

#!/bin/bash

# Значение счетчика и целевая директория
k=1
target_directory="/home/user/ToddCrimson/Pictures/All_MOV"

# Убедитесь, что целевая директория существует
mkdir -p "$target_directory"

# Перебираем все поддиректории и файлы
for dir in /home/user/ToddCrimson/Pictures/iPhone-Media/*; do
    if [[ -d $dir ]]; then  # только если это директория
        for file in "$dir"/*.MOV; do
            # Проверяем, существует ли файл
            if [[ -f $file ]]; then
                # Копируем файл с сохранением временной метки и переименованием
                cp -p "$file" "$target_directory/Mov-$(printf "%08d" "$k").MOV"
                ((k++))
            fi
        done
    fi
done

Запуск скрипта:

  1. Сохраните скрипт в файл, например, copy_images.sh.
  2. Сделайте скрипт исполняемым:
    chmod +x copy_images.sh
  3. Запустите скрипт:
    ./copy_images.sh

Пояснения:

  • Скрипт использует cp -p, чтобы сохранить временные метки оригинальных файлов.
  • Файлы будут переименованы в формате Pic-00000001.jpg, Pic-00000002.jpg и т.д. для JPG и Mov-00000001.MOV, Mov-00000002.MOV и т.д. для MOV.
  • Будьте внимательны при использовании скрипта, особенно если ваши директории содержат много файлов, чтобы избежать переполнения целевой директории.

Этот подход должен помочь вам успешно скопировать файлы с сохранением важной информации о времени создания.

Оцените материал
Добавить комментарий

Капча загружается...