Переместите файлы от подпапок

Я бил головой об это некоторое время, но я - действительно не хороший писатель сценария. Извинения...

Я запускаю Ubuntu/гнома 18.10 и имею большой набор изображений, экспортируемых из Mac моего wifey. Структура каталогов:

year1
  (login dir name with spaces) - Month
    Image names
year2
  ...

как в:

2013
  May 4, 2013
    Image1.jpg
    Image2.jpg
  May 5, 2013
    Image 1.jpg
    Image 3.jpg
  June 22, 2013

То, что я хотел бы:

2013
   January
     All the "january" images...
   February
     All the...

Я могу создать каталоги достаточно легко mkdir {January..December} достаточен. Но я не могу выяснить, как обойти ужасное дерево каталогов (экспортируемый из Mac), переместите изображения и затем удалите ужасный каталог.

1
задан 17 January 2019 в 14:08

3 ответа

Вот такой сценарий:

#!/bin/bash

# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"

MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')

# Walk through the first level directories, located in the current directory and go inside
for year in */
do
    cd "$year"
    # Walk through the months of the year
    for month in "${MONTHS[@]}"
    do
        # Walk through the second level directories
        for dir in */
        do
            # If we have coincidence between the name of the directory and the month
            # go inside, make a new destination directory; ignore character cases^^
            if [[ ${dir^^} =~ ${month^^} ]]
            then
                cd "$dir"
                dest="${DEST}${year}${month}"
                mkdir -p "$dest"
                find . -type f | while IFS= read -r item
                do
                    # Copy the files to the new destination and
                    # add the file's md5sum to its name to prevent files lose
                    filename=$(basename -- "$item")
                    extn="${filename##*.}"
                    name="${filename%.*}"
                    cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
                done
                cd ..
            fi
        done
    done
    cd ..
done

Сценарий должен быть выполнен в первом каталоге уровня, где Ваши изображения расположены. Необходимо настроить целевой каталог - DEST="/tmp/new-order-pictures/". Эта версия сценария полагается, что все файлы находятся в каталогах, которые содержат имя месяца так или иначе. Пример использования:

user@host:~/Pictures$ tree .
.
├── 2013
│  ├── January 17, 2013
│  │  ├── Image1.jpg
│  │  └── Image 3.jpg
│  ├── January 24, 2013
│  │  └── Image2.jpg
│  ├── January 25, 2013
│  │  └── Image 3.jpg
│  ├── June 22, 2013
│  │  └── image1.jpg
│  ├── May 4, 2013
│  │  └── Image1.jpg
│  └── May 5, 2013
│  ├── Image1.jpg
│  └── Image 2.jpg
└── 2014
    ├── January 17, 2014
    │  ├── Image1.jpg
    │  └── Image 3.jpg
    ├── January 24, 2014
    │  └── Image2.jpg
    ├── January 25, 2014
    │  └── Image 3.jpg
    └── May 5
        ├── Image1.jpg
        └── Image 2.jpg

12 directories, 14 files


user@host:~/Pictures$ order.sh 


user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│  ├── Jan
│  │  ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│  │  ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│  │  ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│  │  └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│  ├── Jun
│  │  └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│  └── May
│  ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│  ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│  └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
    ├── Jan
    │  ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
    │  ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
    │  ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
    │  └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
    └── May
        ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
        └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg

7 directories, 14 files

В моем случае называют сценарий order.sh и это расположено в ~/bin, таким образом я могу использовать его в качестве команды оболочки. В примере Вы видите, что структура каталогов изменяется, но количество файлов 14 в обеих структурах.


Вот является другая версия сценария тем использованием mv вместо cp и будет иметь дело также с файлами, которые не находятся в каталогах, которые содержат имя месяца. Прежде, чем запустить этот скрипт это - хорошая идея создать резервную копию исходной структуры каталогов.

#!/bin/bash

# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"

MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')

# Walk through the first level directories, located in the current directory and go inside
for year in */
do

    cd "$year"

    # Walk through the months of the year
    for month in "${MONTHS[@]}"
    do
        # Walk through the second level directories
        for dir in */
        do
            # If we have coincidence between the name of the directory and the month
            # go inside, make a new destination directory; ignore character cases^^
            if [[ ${dir^^} =~ ${month^^} ]]
            then

                cd "$dir"
                dest="${DEST}${year}${month}"
                mkdir -p "$dest"

                while IFS= read -r item
                do
                    # Copy the files to the new destination and
                    # add the file's md5sum to its name to prevent files lose
                    filename=$(basename -- "$item")
                    extn="${filename##*.}"
                    name="${filename%.*}"
                    mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
                done < <(find . -type f)

                cd ..

            fi

        done

    done

    # Dial with the rest of the files for that $year

    dest="${DEST}${year}other"

    while IFS= read -r item
    do
        mkdir -p "$dest"
        filename=$(basename -- "$item")
        extn="${filename##*.}"
        name="${filename%.*}"
        mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
    done < <(find . -type f)

    cd ..

done

Пример использования:

user@host:~/Pictures$ tree .
.
├── 2013
│  ├── January 17, 2013
│  │  ├── Image1.jpg
│  │  ├── Image 3.jpg
│  │  └── video 7.mpg
│  ├── January 25, 2013
│  │  └── Image 3.jpg
│  ├── June 22, 2013
│  │  └── image1.jpg
│  └── May 5, 2013
│  ├── Image1.jpg
│  └── Image 2.jpg
└── 2014
    ├── Apr 7
    │  ├── Image1.jpg
    │  └── Image 2.jpg
    ├── Image 2.jpg
    ├── January 11, 2014
    │  ├── Image1.jpg
    │  └── Image 3.jpg
    ├── some other name
    │  └── some other name file inside.jpg
    ├── some other name file inside.jpg
    └── video 1.avi

9 directories, 15 files

user@host:~/Pictures$ order.sh 

user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│  ├── Jan
│  │  ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│  │  ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│  │  ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│  │  └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│  ├── Jun
│  │  └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│  └── May
│  ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│  └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
    ├── Apr
    │  ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
    │  └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
    ├── Jan
    │  ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
    │  └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
    └── other
        ├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
        ├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
        ├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
        └── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi

8 directories, 15 files

После этого можно войти в целевой каталог и использовать rename команда в for цикл для контакта с длинными именами:

# For each directory on the second level
for dir in */*
do
    cd "$dir"
    rename 's/^.*(\.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
    cd ..
    cd ..
done

Пример:

user@host:~/Pictures$ cd /tmp/new-order-pictures/

user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(\.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done

user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│  ├── Jan
│  │  ├── Image-001.jpg
│  │  ├── Image-002.jpg
│  │  ├── Image-003.jpg
│  │  └── Image-004.mpg
│  ├── Jun
│  │  └── Image-001.jpg
│  └── May
│  ├── Image-001.jpg
│  └── Image-002.jpg
└── 2014
    ├── Apr
    │  ├── Image-001.jpg
    │  └── Image-002.jpg
    ├── Jan
    │  ├── Image-001.jpg
    │  └── Image-002.jpg
    └── other
        ├── Image-001.jpg
        ├── Image-002.jpg
        ├── Image-003.jpg
        └── Image-004.avi

8 directories, 15 files

Или можно измениться (\.[0-9a-zA-Z]+) с (\.jpg), затем на следующем повторении с (\.mpg) (соответственно Image- с Video-), и т.д. Ссылки об этом использовании rename:

1
ответ дан 3 December 2019 в 07:22

Существует приложение, которое может переместить и переименовать файлы в единственной командной строке - exiftool

sudo apt install libimage-exiftool-perl

В моем случае определенная используемая командная строка была

exiftool  '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r

или

exiftool  '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r

в зависимости от которого тег присутствует в изображениях. Если требуемый тег не присутствует, приложение бросает предупреждение и не перемещает тот файл, но продолжает обрабатывать. Это приложение также обрабатывает повторные изображения с той же датой/временем путем добавления числового в конец имени файла.

У меня действительно было несколько изображений без exif данных, и я смог добавить exif данные к изображениям с командой

exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original

Как пример, я поместил некоторые изображения в каталог ~/aa/test1 и выполнил инструмент, поместив вывод в ~/aa/test2. Результаты ниже:

chick@dad:~/aa$ tree .
.
├── test1
│  ├── DSC00018.JPG
│  ├── DSC00022.JPG
│  ├── DSC00024.JPG
│  ├── DSC00025.JPG
│  ├── DSC00026.JPG
│  ├── DSC00028.JPG
│  ├── DSC00031.JPG
│  ├── DSC00033.JPG
│  └── Thumbs.db
└── test2
    └── 2000
        └── 12-December
            ├── 20001222_185523.JPG
            ├── 20001222_200726.JPG
            ├── 20001222_200819.JPG
            ├── 20001222_201205.JPG
            ├── 20001222_201223.JPG
            ├── 20001222_210536.JPG
            ├── 20001222_211858.JPG
            └── 20001222_215950.JPG
2
ответ дан 3 December 2019 в 07:22

Так, я предполагаю, что Вы хотите пошаговое и простое решение. Во-первых, я решил бы проблему Пробела и запятой в папках. Я был бы первый CD в папку года и использование rename сначала удалить Пробел

rename "s/ //g" *

Точно так же удалите запятую

rename "s/,//g" * 

Теперь, когда у меня есть все папки, как желаемый, я создал бы основанное на месяце использование списка

ls | grep "January" > January.txt

Теперь сделайте папку "January"

mkdir January

Затем цикл посредством использования списка xargs скопировать их содержание

cat January.txt | xargs -I {} cp -R {}/. ./January/
0
ответ дан 3 December 2019 в 07:22

Другие вопросы по тегам:

Похожие вопросы: