Автоматически Переименовать файлы от 1 до неограниченного числа

Я осуществил бы рефакторинг код как это. Я нахожу, что этот метод является более четким и легче отладить:

find . -type f -name '*.bmp' |\
  while read BMP
  do
    DIR=$(dirname "$BMP")
    PNG="$(echo $BMP | sed 's/.bmp//g')"
    convert "${BMP}" "${PNG}".png
  done
2
29.10.2015, 09:29
4 ответа

Попробуйте:

n=0; for f in *.jpg; do mv "$f" "$((++n)).jpeg.jpg"; done

Или то же самое, распределенное по нескольким строкам:

n=0
for f in *.jpg
do
    mv "$f" "$((++n)).jpeg.jpg"
done

Как это работает

  • n = 0

    Это инициализирует переменную n n.

  • для f в * .jpg; do

    Это запускает цикл по всем файлам в текущем каталоге, имена которых заканчиваются на .jpg .

  • mv "$ f" "$ ((++ n)). Jpeg.jpg"

    Это переименовывает файлы по вашему желанию. В bash $ ((...)) выполняет арифметические операции. Здесь он увеличивает n каждый раз при запуске.

  • done

    Сигнализирует об окончании цикла.

Этот код будет работать, даже если есть файлы, имена которых содержат пробелы, табуляции, символы новой строки или другие сложные символы.

Порядок

glob test * .in разворачивается в список файлов в алфавитном порядке. Это описано в man bash :

bash сканирует каждое слово на наличие символов *,? И [. Если появляется один из этих символов , то слово рассматривается как шаблон, и заменяется отсортированным по алфавиту списком имен файлов, соответствующих шаблону ( см. Сопоставление с образцом ниже). [Курсив добавлен.]

Обратите внимание, что значение сортировки по алфавиту может зависеть от настроек вашего региона.

2
27.01.2020, 21:59

Поскольку количество файлов может быть «неограниченным», существует встроенный предел размера командной строки. См. https://stackoverflow.com/questions/19354870/bash-command-line-and-input-limit . Поэтому я бы использовал find , чтобы решить эту проблему. Например, в bash:

cd /path/to/directory
n=1
find . -maxdepth 1 -type f -name "*.jpeg.jpg" | sort |  while read file; do
    mv "$file" $n.jpeg.jpg
    let n=n+1
done

Шаги следующие, построчно:

  1. Перейти в соответствующий каталог
  2. Установить счетчик файлов на 1
  3. найти в . (текущий) каталог, и не копаться в каких-либо подкаталогах ( -maxdepth 1 ) и просматривать только обычные файлы -тип f и возвращать только файлы, имена которых совпадают шаблон *. jpeg.jpg , и вывести их имена (по умолчанию). Передайте вывод команды find команде sort, чтобы они были в порядке (sort может обрабатывать очень большие stdin). Передайте вывод сортировки в цикл while / read , который построчно установит каждую строку ввода в файл переменной .
  4. Переместите файл, имя которого хранится в переменной file , в файл, названный переменной $ n , содержащий строку `.jpeg.jpg '
  5. Приращение переменная n
  6. Переход к следующему имени файла.

Таким образом можно обрабатывать очень большой каталог. Он довольно невосприимчив к «странным» (также известным как «символы, не входящие в печатаемый набор ASCII») имен файлов. Его можно сделать даже более защищенным, но я предполагаю, что в этом случае это, вероятно, не нужно (это включает использование параметра -print0 и, возможно, команды xargs ).

1
27.01.2020, 21:59

Эта версия сохранит новые файлы в том же порядке, когда вы перечисляете их в алфавитном порядке (как в выводе ls):

#!/bin/sh
i=0
for f in *.jpeg.jpg
do
     mv "$f" "$(printf '%011d.jpeg.jpg' $i)"
     i=$(expr $i + 1)
done
0
27.01.2020, 21:59
j=0;
for i in `ls`
do
     mv $i $j.jpeg.jpg
     j=`echo $j + 1 | bc`
done
1
27.01.2020, 21:59

Теги

Похожие вопросы