Переименование набора файлов на 001, 002,... на Linux

Изначально у меня был набор изображений формы image_001.jpg, image_002.jpg,...

Я прошел через них и удалил несколько. Теперь я хотел бы переименовать оставшиеся файлы обратно в image_001.jpg, image_002.jpg,...

Есть ли команда Linux, которая будет делать это аккуратно? Я знаком с переименованием, но не вижу ничего, чтобы заказать имена файлов, подобные этому. Я думаю, что, поскольку ls *.jpg перечисляет файлы в порядке (с пробелами), решение должно было передать вывод этого в цикл bash или что-то еще?

Ответ 1

Если я правильно понимаю, у вас есть, например, image_001.jpg, image_003.jpg, image_005.jpg, и вы хотите переименовать в image_001.jpg, image_002.jpg, image_003.jpg.

EDIT: это изменение, чтобы поместить временный файл в текущий каталог. Как отметил Stephan202, это может существенно повлиять, если temp находится в другой файловой системе. Чтобы избежать попадания временного файла в цикл, он теперь проходит через изображение *

i=1; temp=$(mktemp -p .); for file in image*
do
mv "$file" $temp;
mv $temp $(printf "image_%0.3d.jpg" $i)
i=$((i + 1))
done                                      

Ответ 2

Простой цикл (тест с echo, выполнить с помощью mv):

I=1
for F in *; do
  echo "$F" `printf image_%03d.jpg $I`
  #mv "$F" `printf image_%03d.jpg $I` 2>/dev/null || true
  I=$((I + 1))
done

(я добавил 2>/dev/null || true, чтобы подавить предупреждения об идентичных исходных и целевых файлах. Если это вам не по вкусу, перейдите Matthew Flaschen ответ.)

Ответ 3

Попробуйте выполнить script:

numerate.sh

Этот фрагмент кода должен выполнять задание:

./numerate.sh -d <your image folder> -b <start number> -L 3 -p image_ -s .jpg -o numerically -r

Ответ 4

Это делает обратное тому, что вы просите (беря файлы формы *.jpg.001 и конвертируя их в *.001.jpg), но их можно легко изменить для вашей цели:

for file in * 

do

if [[ "$file" =~ "(.*)\.([[:alpha:]]+)\.([[:digit:]]{3,})$" ]]

then

mv "${BASH_REMATCH[0]}" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}.${BASH_REMATCH[2]}"

fi

done

Ответ 5

Некоторые хорошие ответы здесь уже есть; но некоторые полагаются на скрытые ошибки, что не является хорошей идеей (предполагается, что mv будет только ошибкой из-за ожидаемого условия - как насчет всех других reaons mv может быть ошибка?).

Кроме того, это можно сделать немного короче и должно быть лучше указано:

for file in *; do
    printf -vsequenceImage 'image_%03d.jpg' "$((++i))"
    [[ -e $sequenceImage ]] || \
        mv "$file" "$sequenceImage"
done

Также обратите внимание, что вы не должны использовать ваши переменные в сценариях bash.

Ответ 6

Я собирался предложить что-то вроде выше, используя цикл for, итератор, cut -f1 -d "_", затем mv я i.iterator. Похоже, что он уже охватывает другие способы.