mv групповое переименование/перемещение
Почему когда я выполняю команду вида mv *.k {i..j}.k, где i, j это некоторые числа, а k - некоторое расширение, mv выводит ошибку:
указанная цель 'j.k' не является каталогом
при том, что перемещение происходит в этом же каталоге, а i и j подобраны под количество файлов на переименование.
Используемый дистрибутив: Ubuntu 18.04 Bash версии 4.4.20
Ответы (3 шт):
программа mv делает одно из двух:
переименовывает (с перемещением или без) один файл:
$ mv исходный.файл конечный.файлперемещает один или более файлов в указанный каталог. традиционный порядок аргументов:
$ 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
Есть в большинстве дистрибутивов пакет/скрипт rename, немного практичнее голого mv.
~$ ls ./
one.bak
two.bak
three.bak
~$ rename 's/\.bak$//' *.bak
~$ ls ./
one
two
three
Можно так все файлы *.jpg -> *.jpeg:
for i in *.jpg ; do mv -v $i `echo $i | awk -F. '{print $1".jpeg"}'`;done
но если будут в имени файла точки, то не сработает!