mv групповое переименование/перемещение

Почему когда я выполняю команду вида mv *.k {i..j}.k, где i, j это некоторые числа, а k - некоторое расширение, mv выводит ошибку:

указанная цель 'j.k' не является каталогом

при том, что перемещение происходит в этом же каталоге, а i и j подобраны под количество файлов на переименование.

Используемый дистрибутив: Ubuntu 18.04 Bash версии 4.4.20


Ответы (3 шт):

Автор решения: aleksandr barakin

программа mv делает одно из двух:

  1. переименовывает (с перемещением или без) один файл:

    $ mv исходный.файл конечный.файл
    
  2. перемещает один или более файлов в указанный каталог. традиционный порядок аргументов:

    $ mv файл ... каталог
    

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

    $ mv -t каталог файл ...
    

переименовать же несколько файлов за один вызов эта программа не умеет.


чтобы не писать кучу отдельных команд переименования/перемещения, можно воспользоваться языком программирования, встроенным в программу-оболочку. вот такой, например, микро-программой (подходит для любой posix-совместимой оболочки):

$ n=1; for f in *.k; do mv "$f" "$n.zzz"; n=$((n+1)); done

я намеренно использовал в качестве новых имена, заканчивающиеся другим суффиксом, не как у исходных файлов — .k — а .zzz (это просто для примера). иначе можно потерять информацию: например, если есть два файла 0.k и 1.k, то первое же переименование — 0.k в 1.k — удалит существующий файл 1.k.


альтернативный вариант — воспользоваться perl-овой реализацией программы rename (при нескольких установленных реализациях непосредственно к этой реализации можно обратиться по её «родному» имени — prename).

например:

$ prename 's/.*\.k$/sprintf "%03d.zzz", ++$a/e' *.k -n
rename(0.k, 001.zzz)
rename(1.k, 002.zzz)
$ prename 's/.*\.k$/sprintf "%03d.zzz", ++$a + 20/e' *.k -n
rename(0.k, 021.zzz)
rename(1.k, 022.zzz)
$ prename 's/.*\.k$/sprintf "%03d.zzz", $a++ + 30/e' *.k -n
rename(0.k, 030.zzz)
rename(1.k, 031.zzz)

и т.д. и т.п.

дополнительная информация: $ man prename

→ Ссылка
Автор решения: Hellseher

Есть в большинстве дистрибутивов пакет/скрипт rename, немного практичнее голого mv.

~$ ls ./
one.bak
two.bak
three.bak

~$ rename 's/\.bak$//' *.bak

~$ ls ./
one
two
three

https://metacpan.org/pod/distribution/File-Rename/rename.PL

→ Ссылка
Автор решения: user583902

Можно так все файлы *.jpg -> *.jpeg:

for i in *.jpg ; do mv -v $i `echo $i | awk -F. '{print $1".jpeg"}'`;done

но если будут в имени файла точки, то не сработает!

→ Ссылка