@jintaxi
Чуть-чуть програю для себя.

Как максимально просто и быстро переименовать файлы по маске?

Здравствуйте, уважаемые.

Как мне заменить имена файлов с
1, 2, 3, ... 10, 11, 12, ... 100, 101, 102
на
001, 002, 003, ... 010, 011, 012, ... 100, 101, 102

Желательно, что б программа или что бы то ни было, могла бы сама понимать какое у меня самое большое количество разрядов (или ручками ввести для каждой папки с файлами, совсем не критично) и сколько надо нулей ставить в начало.

Знатоки, подскажите, пожалуйста, как это можно сделать через регулярное выражение (желательно) в, например, Total Commander или Python, или bat, или bash.

P.S. Нужно перенумеровать (такое слово, интересно, есть?) как из маски (1)*, (2)*, (3)*, ... (100)*, (101)*, так и маски названий файлов наподобие *№1, *№2, *№3, ... *№100, *№101, *№102.
  • Вопрос задан
  • 1037 просмотров
Решения вопроса 2
Shellr57s
@Shellr57s
tWaIkkv.png
Ну тут суть, а что более конкретно вам нужно для других случаев я не понял.
Ответ написан
Самый простой вариант сделать прсто на файнд, единственное что в вашем примере всего два варианта по этому нет делать никаких циклов проще два раза прогнать условие. Для тестов замени mv на cp или тестовой папочке.
find . -type f -name '[0-9][0-9]\.txt' -exec bash -c 'mv $0 0${0#./}' {} \;
find . -type f -name '[0-9]\.txt' -exec bash -c 'mv $0 00${0#./}' {} \;


Вывод до

[bitrix@centos-4gb-hel1-1 test]$ ls
10.txt  1.txt  2.txt  333.txt


Вывод после

[bitrix@centos-4gb-hel1-1 test]$ ls
001.txt  002.txt  010.txt 333.txt



find -поиск рекурсивный
. где
-type f- только файлы
-name- имя файла в данном сулчае ругулярка
-execвыполнить с найденм, опция самого find
-bash - bash ( поскольку нам нужно удалить ./ из имени файла а сам find это может сделать но нам нужно и оставить предидущий вариант для mv а тут уже все )
{} подставить в exec вывод find
\;экранируем и закрываем find

А еще лучше скажите для чего вы это делаете, возможно мы идем не тем путем.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Lynn
@Lynn
nginx, js, css
Ну на bash вручную несложно:
for i in {1..99}; do a=00$i; mv $i ${a: -3}; done
Ответ написан
Vindicar
@Vindicar
RTFM!
1. Составляешь список интересующих тебя файлов с помощью модуля glob или pathlib.
2. С помощью регулярного выражения "\d+" (модуль re), вытаскиваешь из имен файлов последовательности цифр. Если их несколько, тебе придётся придумать критерий, какую брать (например, последнюю). Определяешь наибольшее количество разрядов.
3. Снова проходишься по списку имен с помощью re.sub(). Второй аргумент re.sub() может быть не только строкой для замены, но и функцией - просто делаешь функцию, которая дополняет входящую строку нулями до желаемой ширины и возвращает её.
4. Если новая строка (с заменой) отличается от оригинальной, то переименовываешь файл с оригинальным именем в файл с новым именем, иначе оставляешь как есть.
Ответ написан
Комментировать
saboteur_kiev
@saboteur_kiev Куратор тега Python
software engineer
Накидал какое-то рабочее решение.
Должно работать с разными именами файлов в текущей директории, главное чтобы в файле был только один кусок с числом.

То есть с таким набором файлов справится: file1.jpg file02.jpg file0035.jpg 36file.jpg, лишь бы числа не пересекались

А с таким - НЕ справится: file1_1.jpg 01_file_02.jpg

max=$(ls -1 | grep -oP "[0-9]*"|sort -n|tail -n1)
length=$(sed "s/^0*//g"<<<"$max"|xargs expr length)
echo "Max number found: [$max], max length: [$length]"

ls -1|while read oldname; do
  oldnum="$(grep -oP "[0-9]*"<<<"oldname")"
  newnum=$(printf "%0${length}d" $(sed "s/^0*//g"<<<"$oldnum"))
  newname=$(sed "s/$oldnum/$newnum/g"<<<"$oldname")
  if [ -f "$newname" ]; then
    echo "Kinly check the following files manually: $oldname $newname"
  else
    echo "Renaming [$oldname] to [$newname]"
    # mv "$oldname" "$newname"
done


p.s. после проверки вывода, расскомментировать строчку с "# mv "
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы