Скрипт оболочки для рекурсивного копирования файлов с уникальными именами в новые папки - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь реструктурировать мои файлы в новые каталоги на основе имен файлов.Это делается с помощью GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17) на OS X High Sierra

В настоящее время у меня есть родительский каталог, с 2 наборами подкаталогов, с более 100 подкаталогами, а затем набор изображений с именами файлов, которые распространены среди 3000или около того файлов, которые у меня есть.

Итак, Parent (dir) -> Подкатегории (dirs) -> Более глубокие подкатегории (dirs) -> Файлы

Все имена файлов очень похожи, то есть логин.png или splash.png и у меня, вероятно, только 40 уникальных имен файлов в 3000 файлах.Однако подкатегории уникальны.

Я пытаюсь рекурсивно скопировать все идентичные имена файлов (то есть все файлы login.png) в новую папку, но переименовать их все с произвольным уникальным идентификатором.Этот уникальный идентификатор не имеет значения вообще.Это может быть произвольное число или даже имя родительского каталога (например, login_subdirectoryname.png)

Я пробовал несколько вещей, чтобы даже получить список всех доступных файлов:

Так что используя что-токак это, по крайней мере, показывает мне все доступные файлы:

find ./Parent -name "*.PNG" -type f -exec echo_name.sh basename {} \;

Где echo_name.sh просто:

echo_name(){
    echo $1
}
echo_name $1

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

Так что мне нужно выполнить две вещи здесь...

A) Поддерживать некоторую уникальную переменную для подсчета в функции find, которая передается в echo_name.sh, поэтому каждое имя файла просто увеличивается на единицу (т. Е. login_1.png), или добавление имени родительского каталога (т. е. login_thissubcategory. png), чтобы избежать дублирования имен файлов при создании фактического cp

B) Определить, что такое строгое имя файла без расширения, ипуть, а также определить путь.Поэтому моя функция должна знать:

  • . / Parent / subcategory / deeper_subcategory / login.PNG
  • deeper_subcategory
  • login

Я знаю, что это сложная реструктуризация, но любая помощь приветствуется.

1 Ответ

0 голосов
/ 01 октября 2018

Вы можете использовать find и xargs в сочетании со встроенным сценарием bash, чтобы выполнить это:

$ mkdir -p parent/category{1,2}/subcat{a,b,c,d,e}/
$ touch parent/category{1,2}/subcat{a,b,c,d,e}/{login,splash}.png
$ find . -type f | nl | xargs -n2 -I@ bash -c 'set -- @; b=${2##*/}; echo cp $2 ${b%.*}_$1.${b##*.}'
cp ./parent/category1/subcata/login.png login_1.png
cp ./parent/category1/subcata/splash.png splash_2.png
cp ./parent/category1/subcatb/login.png login_3.png
cp ./parent/category1/subcatb/splash.png splash_4.png
cp ./parent/category1/subcatc/login.png login_5.png
cp ./parent/category1/subcatc/splash.png splash_6.png
cp ./parent/category1/subcatd/login.png login_7.png
cp ./parent/category1/subcatd/splash.png splash_8.png
cp ./parent/category1/subcate/login.png login_9.png
cp ./parent/category1/subcate/splash.png splash_10.png
cp ./parent/category2/subcata/login.png login_11.png
cp ./parent/category2/subcata/splash.png splash_12.png
cp ./parent/category2/subcatb/login.png login_13.png
cp ./parent/category2/subcatb/splash.png splash_14.png
cp ./parent/category2/subcatc/login.png login_15.png
cp ./parent/category2/subcatc/splash.png splash_16.png
cp ./parent/category2/subcatd/login.png login_17.png
cp ./parent/category2/subcatd/splash.png splash_18.png
cp ./parent/category2/subcate/login.png login_19.png
cp ./parent/category2/subcate/splash.png splash_20.png

Первые две строки просто настраивают тестовый жгут.Последняя строка интересная.Давайте разберем это:

find . -type f | \ # use find to locate the files -- change this as needed
    nl | \ # number each line -- this gives us the unique id for each
    xargs -n2 -I@ \ # pass the line number and full file name to each...
        bash -c \ # ... instance of bash we start
            'set -- @; b=${2##*/}; echo cp $2 ${b%.*}_$1.${b##*.}'

Мясо внутри кавычек выглядит следующим образом:

  • set -- @ разделить два аргумента на $1 (строка #) и $2 (полный путь к файлу)
  • b=${2##*/} получает базовое имя файла
  • echo cp $2 повторяет запуск команды cp - для этого удалите echo, настройтепри необходимости
  • ${b%.*}_$1.${b##*.} получает часть имени файла без расширения, добавляет _ в конец, добавляет номер строки, затем добавляет обратно.часть расширения.

Я отказался от обработки имен файлов с пробелами, нулями, новыми строками и другими не-ASCII-символами, так как OP предположил, что это не проблема.Если является проблемой, потребуются дополнительные методы.

...