Переименование файлов путем добавления суффикса «cycling»

Переименование файлов путем добавления суффикса «cycling»

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

file1.tif
file2.tif
file3.tif
file4.tif
file5.tif
file6.tif
file7.tif...

Я хочу добавить суффикс «циклирование» c1и c2, c3чтобы получить имена файлов:

file1c1.tif
file2c2.tif
file3c3.tif
file4c1.tif
file5c2.tif
file6c3.tif
file7c1.tif...

И это во всех подкаталогах верхнего каталога.

Но я не могу понять, как это сделать.

Возможно ли это? Как?

решение1

С помощью find+ на основе Perl prename(также известного как renameнекоторые ранние версии Ubuntu) вы можете сопоставить последовательность цифр перед литералом ., а затем записать ее в желаемом формате, используя деление по модулю, например

find . -name '*.tif' -execdir prename -vn -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

( -vnфлаги позволяют выполнить «пробный прогон», чтобы увидеть, как будут переименованы файлы перед фиксацией).


Пример дан

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   ├── file4.tif
│   ├── file5.tif
│   ├── file6.tif
│   └── file7.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

4 directories, 14 files

Затем

find . -name '*.tif' -execdir prename -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

результаты в

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   ├── file4c1.tif
│   ├── file5c2.tif
│   ├── file6c3.tif
│   └── file7c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

4 directories, 14 files

решение2

Редактировать на основе комментария:

Если вы хотите циклически переключать счетчик, например, <number>от c<number>1 до 3:

Пробный прогон:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do 
        echo mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Действие:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do 
        mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Пример:

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   └── file4.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

$ shopt -s globstar
$ for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do \
    echo mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
/home/foobar/bar
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
mv -i file4.tif file4c1.tif
/home/foobar/foo
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
/home/foobar/foo/egg
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
/home/foobar/spam
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif

$ for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do \
    mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   └── file4c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

Оригинальный ответ:

С bash:

shopt -s globstar
for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob \
    && for f in file*.tif; do echo mv -i "$f" "${f%.tif}"c${count}.tif; \
        ((count++)); done ); done
  • Здесь мы перебираем имена каталогов, globstarопция оболочки позволяет нам проходить по каталогам рекурсивно.

  • Внутренняя часть ()выполняется в подоболочке, это сделано для предотвращения ее cdизменения в текущей оболочке.

  • Мы cdзаходим в каталоги, находим file*.tifфайлы и переименовываем их по мере необходимости.

  • сохранение увеличивающегося счетчика, countдля каждого файла при переименовании


Вышеприведенный пример — это пробный запуск, который покажет вам каталог, в котором будет выполнено переименование, и какая mvкоманда будет запущена. Если все устраивает, выполните:

shopt -s globstar
for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && \
  for f in file*.tif; do mv -i "$f" "${f%.tif}"c${count}.tif; ((count++)); done ); done

Есть оговорка, что поскольку shell выполняет лексическую сортировку, то файлы, например, file10.tifбудут переименованы раньше, чем file2.tif. Если вы этого не хотите, выполните сортировку перед переименованием или используйте опцию zshwith numericglobsort.

решение3

Спасибо heemayl, все получилось. Нам пришлось немного изменить указанный цикл инкремента цикла, так как он не работал у нас. Мы изменили: if ((count=3)) на: if (("$count"==3)) Окончательный код, который мы теперь успешно используем, выглядит так:

    shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in *.tif; do 
       echo mv -i "$f" "${f%.tif}"c${count}.tif

if (("$count"==3)); then 
count=1
        else 
((count++))
        fi
     done ) 
done

Еще раз спасибо heemayl за его/ее помощь и терпение...

Связанный контент