Как переименовать файлы через bash

Добрый вечер!
Подскажите, как переименовать файлы с именами 1053-84744_ SOCHI 2014, white.jpg в 1053-84744.jpg
Смог дойти только до:

rename -n 'y/_/{%.jpg} /' *
Но результат не тот что нужно.
Может кто знает как это сделать?
Семён Лобачевский
22 июня 2015, 18:38
modx.pro
1
1 379
0

Комментарии: 6

Василий Наумкин
23 июня 2015, 05:54
1
+1
На bash я такое написать не смогу, но сделал на Python:
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import os
import re


def rename(file_path):
    global duplicate
    base_path = os.path.dirname(os.path.realpath(file_path))
    filename = os.path.basename(file_path)
    extension = os.path.splitext(filename)[1]

    new_filename = re.sub(r'[^0-9\_\-]', '', filename)
    new_filepath = base_path + '/' + new_filename + extension
    if new_filepath == file_path:
        print(new_filename + extension)
        return

    while os.path.isfile(new_filepath):
        tmp_filename = os.path.basename(new_filepath)
        tmp_basename = os.path.splitext(tmp_filename)[0]
        idx = 1
        match = re.search(r'.*?\-(\d+)$', tmp_basename)
        if match:
            idx = int(match.group(1)) + 1
            new_filename = re.sub(r'\-(\d+)$', '-' + str(idx), tmp_basename)
        else:
            new_filename += '-' + str(idx)
        new_filepath = base_path + '/' + new_filename + extension
    try:
        os.rename(file_path, new_filepath)
        print("{0} => {1}".format(filename, new_filename + extension))
    except Exception as e:
        print(e)


if __name__ == "__main__":
    if len(sys.argv) < 2:
        exit("Нужно указать имя файла или директории")
    path = os.path.realpath(sys.argv[1].strip())

    if os.path.isdir(path):
        files = os.listdir(path)
        for file in files:
            rename(path + '/' + file)
    elif os.path.isfile(path):
        rename(path)

Файл нужно сделать исполняемым, проверить наличие Python3 и путь к нему на сервере, а затем вызывать с указанием имени файла или путём к директории.

Скрипт переименует все файлы так, что останутся только символы 0-9- и _.

Если файл с новым именем уже есть в директории, то ему (имени) будет добавлена цифра на конце. Во время работы скрипта выводятся имена всех обработанных файлов.

Благодарность можно перечислять вот здесь.

Скрипт поставляется «как есть» — вы используете его на свой страх и риск. Претензии по работе скрипта не принимаются.
    Воеводский Михаил
    23 июня 2015, 06:24
    0
    Василий, а не проще было эту задачку небольшим скриптом на PHP решить?

    Не холивара ради, а просвещения для.
      Василий Наумкин
      23 июня 2015, 06:43
      0
      Да её, наверное, и на bash можно решить, но я написал на Python.

      Напиши на PHP этот небольшой скрипт, сравним.
      Семён Лобачевский
      23 июня 2015, 07:46
      0
      Класс, спасибо, всё получилось!
    Игорь Зябко
    Игорь Зябко
    23 июня 2015, 07:17
    +1
    Тестовый набор
    $ ls -1
    1053-84744_ SOCHI 2014, white.jpg
    1053-84744_ SOCHI 2014, не вайт.jpg
     пробел впереди 1054-84741_ SOCHI 2014, white и сзади .jpg

    На посмотреть
    $ rename --no-act 's/.*(\d{4}-\d{5}).*/$1.jpg/' *.jpg
    1053-84744_ SOCHI 2014, white.jpg renamed as 1053-84744.jpg
    1053-84744_ SOCHI 2014, не вайт.jpg renamed as 1053-84744.jpg
     пробел впереди 1054-84741_ SOCHI 2014, white и сзади .jpg renamed as 1054-84741.jpg

    В действии
    $ rename --verbose 's/.*(\d{4}-\d{5}).*/$1.jpg/' *.jpg
    1053-84744_ SOCHI 2014, white.jpg renamed as 1053-84744.jpg
    1053-84744_ SOCHI 2014, не вайт.jpg not renamed: 1053-84744.jpg already exists
     пробел впереди 1054-84741_ SOCHI 2014, white и сзади .jpg renamed as 1054-84741.jpg

    Результат
    $ ls -1
    1053-84744.jpg
    1053-84744_ SOCHI 2014, не вайт.jpg
    1054-84741.jpg

    С дубликатами придется решать, как Василий написал, самостоятельно.
    Непосредственно rename может их переписать ключом --force
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      6