Вопрос:

Как обнулить числа в именах файлов в Bash?

bash rename

22818 просмотра

8 ответа

2340 Репутация автора

Как лучше всего использовать Bash для переименования файлов в виде:

(foo1, foo2, ..., foo1300, ..., fooN)

С именами файлов с добавлением нуля:

(foo00001, foo00002, ..., foo01300, ..., fooN)
Автор: Trastle Источник Размещён: 11.09.2008 03:25

Ответы (8)


2 плюса

52541 Репутация автора

Следующие будут делать это:

for i in ((i=1; i<=N; i++)) ; do mv foo$i `printf foo%05d $i` ; done

РЕДАКТИРОВАТЬ: изменено для использования ((я = 1, ...)), спасибо mweerden !

Автор: dF. Размещён: 11.09.2008 03:41

0 плюса

6404 Репутация автора

Вот быстрое решение, которое предполагает префикс фиксированной длины (ваш "foo") и заполнение фиксированной длины. Если вам нужна большая гибкость, возможно, это будет, по крайней мере, полезной отправной точкой.

#!/bin/bash

# some test data
files="foo1
foo2
foo100
foo200
foo9999"

for f in $files; do
    prefix=`echo "$f" | cut -c 1-3`        # chars 1-3 = "foo"
    number=`echo "$f" | cut -c 4-`         # chars 4-end = the number
    printf "%s%04d\n" "$prefix" "$number"
done
Автор: amrox Размещён: 11.09.2008 03:43

27 плюса

39570 Репутация автора

Решение

В случае Nесли априори не зафиксировано:

 for f in foo[0-9]*; do mv $f `printf foo%05d ${f#foo}`; done
Автор: Chris Conway Размещён: 11.09.2008 03:47

4 плюса

12038 Репутация автора

Чистый Bash, никаких внешних процессов, кроме «mv»:

for file in foo*; do
  newnumber='00000'${file#foo}      # get number, pack with zeros
  newnumber=${newnumber:(-5)}       # the last five characters
  mv $file foo$newnumber            # rename
done
Автор: Fritz G. Mehner Размещён: 03.02.2009 08:43

17 плюса

1891 Репутация автора

У меня был более сложный случай, когда имена файлов имели постфикс, а также префикс. Мне также нужно было выполнить вычитание числа из имени файла.

Например, я хотел foo56.pngстать foo00000055.png.

Надеюсь, это поможет, если вы делаете что-то более сложное.

#!/bin/bash

prefix="foo"
postfix=".png"
targetDir="../newframes"
paddingLength=8

for file in ${prefix}[0-9]*${postfix}; do
  # strip the prefix off the file name
  postfile=${file#$prefix}
  # strip the postfix off the file name
  number=${postfile%$postfix}
  # subtract 1 from the resulting number
  i=$((number-1))
  # copy to a new name with padded zeros in a new folder
  cp ${file} "$targetDir"/$(printf $prefix%0${paddingLength}d$postfix $i)
done
Автор: Michael Baltaks Размещён: 13.09.2010 11:54

51 плюса

24586 Репутация автора

Это не чистый bash, но намного проще с renameкомандой:

rename 's/\d+/sprintf("%05d",$&)/e' foo*
Автор: KARASZI István Размещён: 30.12.2010 10:23

5 плюса

2835 Репутация автора

Команда oneline, которую я использую, такова:

ls * | cat -n | while read i f; do mv "$f" `printf "PATTERN" "$i"`; done

PATTERN может быть, например:

  • переименовать с помощью счетчика приращений: %04d.${f#*.}(сохранить оригинальное расширение файла)
  • переименовать с приращением счетчика с префиксом: photo_%04d.${f#*.}(сохранить оригинальное расширение)
  • переименуйте счетчик приращений и измените расширение на jpg: %04d.jpg
  • переименовать с помощью счетчика приращений с префиксом и базовым именем файла: photo_$(basename $f .${f#*.})_%04d.${f#*.}
  • ...

Вы можете отфильтровать файл, чтобы переименовать, например, с ls *.jpg | ...

У вас есть переменная, fкоторая является именем файла и iсчетчиком.

Для вашего вопроса правильная команда:

ls * | cat -n | while read i f; do mv "$f" `printf "foo%d05" "$i"`; done
Автор: Pioz Размещён: 08.08.2017 01:22

0 плюса

5899 Репутация автора

Мое решение заменяет числа, везде в строке

for f in * ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf "%04d" $number`
    echo $f | sed "s/${number}/${padded}/";
done

Объяснение:

Перебирая список файлов

Цикл: for f in * ; do ;doneперечисляет все файлы и передает каждое имя файла как $fпеременную в тело цикла.

Схватив номер из строки

С echo $f | sedпеременными мы трубой $fдля sedпрограммирования.

В команде sed 's/[^0-9]*//g', часть [^0-9]*с модификатором ^указывает на совпадение с шаблоном, состоящим из нескольких цифр (а не числа), и затем удаляет его с пустой заменой //. Итак, мы отбрасываем все, что не является числом, и получаем число.

Далее мы присваиваем результат numberпеременной. Не забудьте не ставить пробелы в присваивании, например number = …, потому что вы получаете другое поведение.

Мы присваиваем результат выполнения команды переменной, оборачивая команду символами обратного удара `.

Нулевое заполнение

Команда printf "%04d" $numberменяет формат числа на 4 цифры и добавляет нули, если наш номер содержит менее 4 цифр.

Замена числа на набранное нулями число

Мы используем sedснова с заменой команды, как s/substring/replacement/. Чтобы интерпретировать наши переменные, мы используем двойные кавычки и подставляем наши переменные таким образом ${number}.


Приведенный выше скрипт просто печатает преобразованные имена, поэтому давайте сделаем реальную работу по переименованию:

for f in *.js ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf "%04d" $number`
    new_name=`echo $f | sed "s/${number}/${padded}/"`
    mv $f $new_name;
done

Надеюсь, это кому-нибудь поможет.

Я потратил несколько часов, чтобы понять это.

Автор: AntonAL Размещён: 26.02.2019 03:17
Вопросы из категории :
32x32