Как вы перемещаете файлы с определенным расширением файла в нескольких каталогах, один каталог глубже в соответствующих каталогах? - PullRequest
1 голос
/ 14 апреля 2019

Я надеюсь, что кто-то может мне помочь, я ищу помощь со сценарием bash для перемещения файлов по расширению из нескольких каталогов, на один каталог глубже в соответствующих каталогах.

Например, у меня естькаталог «Проекты», в котором есть несколько каталогов «Проект 001, Проект 002, Проект 003» и т. д.У меня есть файлы «.JPG» в этих папках, и я хочу поместить их в папку «JPG» в соответствующей папке проекта - как бы я сделал это с помощью скрипта bash, поскольку их слишком много, чтобы делать вручную?

Чтобы усложнить задачу, в некоторых из этих папок проекта уже есть папки 'JPG', а в некоторых из них уже есть некоторые файлы в виде дубликатов, поэтому я думаю, что мне нужно добавить подтверждение перезаписи в него.слишком по имени файла.

Я знаю немного bash, но это немного над моей головой, поэтому любая помощь будет принята с благодарностью.

Спасибо,

/ Хами

Это использует CLI на Ubuntu Server 18.04 LTS, на диске с тысячами каталогов с именами людей - пробелами, круглыми скобками и различными символами юникода, такими как японский и европейский.Названия каталогов различны и не имеют конкретной формулы.

В идеале я бы хотел перейти от этого:

  • Проекты
    • Проект 001
      • Изображение 001.jpg
    • Проект 002
      • Изображение 002.jpg
      • Изображение 003.jpg
    • Проект 003

... на это:

  • Проекты
    • Проект 001
      • JPG
        • Изображение 001.jpg
    • Проект 002
      • JPG
        • Изображение 002.jpg
        • Изображение 003.jpg
    • Проект 003

1 Ответ

0 голосов
/ 14 апреля 2019

Вы можете делать все, что вам нужно, с помощью find, который ищет все *.jpg файлы, и простым сценарием helper , вызываемым параметром -exec для find для создания каталога jpgи переместите все .jpg файлы в новый каталог.

Вспомогательный скрипт просто получит абсолютное имя файла, используя readlink -f и затем используя быстрое расширение параметра , чтобы обрезать последний /... компонент из абсолютного имени файла для получения полного пути.Тогда это просто вопрос создания каталога jpg в конце пути и перемещения файла в новый каталог.

Ваш вспомогательный скрипт (я назвал его helper.sh) может быть:

#!/bin/sh

test -z "$1" && exit                        ## validate 1 argument given or exit

full=$(readlink -f "$1")                    ## get full filename
dir="${full%/*}"                            ## get full path

test "${full##*.}" = 'jpg' || exit          ## test extension is jpg or exit

test -z "$dir" && dir="/"                   ## check if file was in / (root) 

test -d "$dir/jpg" || mkdir -p "$dir/jpg"   ## check/create jpg dir at end of path

mv "$full" "$dir/jpg"                       ## move file into new jpg dir

( примечание: после создания вспомогательного скрипта, убедитесь, что вы сделали его исполняемым с chmod +x helper.sh)

Оригинальные проектыДерево каталогов

$ tree Projects/
Projects/
├── Project_001
│   └── Image_001.jpg
├── Project_002
│   ├── Image_002.jpg
│   └── Image_003.jpg
└── Project_003

Ваша команда find, работающая с каталогом Projects, вызывающая вспомогательный скрипт для каждого файла, будет:

$ find Projects/ -type f -name "*jpg" -exec ./helper.sh '{}' \;

Результирующие проектыДерево каталогов

$ tree Projects/
Projects/
├── Project_001
│   └── jpg
│       └── Image_001.jpg
├── Project_002
│   └── jpg
│       ├── Image_002.jpg
│       └── Image_003.jpg
└── Project_003

Дайте мне знать, если у вас есть дополнительные вопросы.

Сохранение файлов уже в каталоге jpg

Per-yourдополнительный комментарий, чтобы сохранить файлы .jpg, уже находящиеся в каталоге jpg в ваших проектах, все, что вам нужно сделать, это добавить одну дополнительную проверку.Если последний компонент пути уже jpg, просто выйдите из помощника, например,

test "${dir##*/}" = 'jpg' && exit           ## if already in jpg dir, exit

Показано в контексте в helper.sh:

test -z "$1" && exit                        ## validate 1 argument given or exit

full=$(readlink -f "$1")                    ## get full filename
dir="${full%/*}"                            ## get full path (trim last /*)

test "${dir##*/}" = 'jpg' && exit           ## if already in jpg dir, exit
test "${full##*.}" = 'jpg' || exit          ## test extension is jpg or exit
...

Исходные проектыДерево каталогов (с существующим jpg)

$ tree Projects/
Projects/
├── Project_001
│   ├── Image_001.jpg
│   └── jpg
│       └── Image_000.jpg
├── Project_002
│   ├── Image_002.jpg
│   ├── Image_003.jpg
│   └── jpg
│       ├── Image_000.jpg
│       └── Image_001.jpg
└── Project_003

Результирующие проекты Дерево каталогов

$ tree Projects/
Projects/
├── Project_001
│   └── jpg
│       ├── Image_000.jpg
│       └── Image_001.jpg
├── Project_002
│   └── jpg
│       ├── Image_000.jpg
│       ├── Image_001.jpg
│       ├── Image_002.jpg
│       └── Image_003.jpg
└── Project_003
...