Вы можете использовать утилиту printf
для вставки, например,
$(ls|grep "A-B-$(printf '%06d' $sequencenumber)-.*"|wc -l)
Два момента:
$(foo)
являются стандартными, вложенные бэкграунды не так переносимыprintf
полезна не только для вставки. Не проверено:
zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)
Вторая строка удаляет все пустые каталоги, даже те, в которых раньше не было файла. Это можно обойти с помощью пользовательской оболочки mv
, которая записывает, из каких каталогов перемещаются объекты.
Обратите внимание, что при этом передаются символические ссылки на каталоги в текущем каталоге.
Не проверено.
rename / ' - ' */*/
rmdir -- */ 2>/dev/null
Обратите внимание, что при этом проходятся символические ссылки на каталоги в текущем каталоге и в его подкаталогах. Вторая строка удаляет все пустые каталоги, даже те, в которых раньше не было файла.
Не проверено.
prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null
Обратите внимание, что при этом проходятся символические ссылки на каталоги в текущем каталоге и в его подкаталогах. Вторая строка удаляет все пустые каталоги, даже те, в которых раньше не было файла.
Вот более сложный подход, который удаляет только те каталоги, из которых он что-то переименовал. Опять же, не проверено.
prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/
Что-то вроде этого?
#!/bin/sh
for topdir in */; do
topdir_name=$( basename "$topdir" )
for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )
newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done
rmdir "$topdir"
done
Это проходит через все каталоги верхнего -уровня в текущем каталоге (названия групп ). Для каждого такого каталога он проходит через его подкаталоги (по названиям альбомов ). Для каждой пары названия группы и названия альбома создается новый каталог, в который перемещаются файлы из подкаталога. Подкаталоги альбомов удаляются после обработки, как и исходные каталоги верхнего уровня группы -.
Вызовы rmdir
завершатся ошибкой, если какой-либо каталог содержит скрытые имена файлов или если не удалось создать какой-либо из новых каталогов.
Это полностью непроверенный код. Запустите его на резервной копии -ваших файлов.
Рассматривали ли вы со стратегической точки зрения, вместо того чтобы перемещать файлы, оставить текущую структуру на месте и создать ссылки для новой структуры, которую вы хотите?
Тактически схема, которая будет выполнять эту работу, выглядит следующим образом:
find. -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c \
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}
find
находит все каталоги ровно на два уровня глубже текущего рабочего каталога, который должен быть каталогом, содержащим группы. :таким образом, на два уровня глубже находятся названия альбомов под названиями групп. 1xargs
использует каждый путь, содержащий альбом, и вызывает встроенный сценарий bash. bash -c '...'
принимает путь к альбому в качестве первого аргумента, разбивая этот путь на две части :группу($b
)и альбом($a
). Наконец, сценарий собирает имена в нужный формат и связывает новое имя каталога с исходным каталогом. Обратите внимание, что в этом примере ссылки будут создаваться в том же каталоге, из которого вы начинаете, а также в том же каталоге, где находятся названия групп.
Вы можете -и должны -изменить описанную выше ln
стратегию, чтобы она соответствовала вашим намерениям. mv
с правильными путями, если вы физически хотите изменить порядок, или ln
, если вы хотите создать удобный «представление» на носителе. Важными частями сценария bash являются:
$b
название группы. Всегда цитируйте его:"$b"
. $a
название альбома. Всегда цитируйте его :"$a"
. $1
физический путь к каталогу альбома. Всегда цитируйте его :"$1"
. 1 Я считаю, что m{ax,in}depth
поддерживаются GNU и некоторыми BSD find
, но не POSIX :, и в этом случае полагайтесь на */*
или аналогичную гимнастику оболочки.