Я осуществил бы рефакторинг код как это. Я нахожу, что этот метод является более четким и легче отладить:
find . -type f -name '*.bmp' |\
while read BMP
do
DIR=$(dirname "$BMP")
PNG="$(echo $BMP | sed 's/.bmp//g')"
convert "${BMP}" "${PNG}".png
done
Попробуйте:
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 сканирует каждое слово на наличие символов *,? И [. Если появляется один из этих символов , то слово рассматривается как шаблон, и заменяется отсортированным по алфавиту списком имен файлов, соответствующих шаблону ( см. Сопоставление с образцом ниже). [Курсив добавлен.]
Обратите внимание, что значение сортировки по алфавиту может зависеть от настроек вашего региона.
Поскольку количество файлов может быть «неограниченным», существует встроенный предел размера командной строки. См. 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
Шаги следующие, построчно:
найти
в .
(текущий) каталог, и не копаться в каких-либо подкаталогах ( -maxdepth 1
) и просматривать только обычные файлы -тип f
и возвращать только файлы, имена которых совпадают шаблон *. jpeg.jpg
, и вывести их имена (по умолчанию). Передайте вывод команды find команде sort, чтобы они были в порядке (sort может обрабатывать очень большие stdin). Передайте вывод сортировки в цикл while
/ read
, который построчно установит каждую строку ввода в файл переменной
. file
, в файл, названный переменной $ n
, содержащий строку `.jpeg.jpg ' Таким образом можно обрабатывать очень большой каталог. Он довольно невосприимчив к «странным» (также известным как «символы, не входящие в печатаемый набор ASCII») имен файлов. Его можно сделать даже более защищенным, но я предполагаю, что в этом случае это, вероятно, не нужно (это включает использование параметра -print0
и, возможно, команды xargs
).
Эта версия сохранит новые файлы в том же порядке, когда вы перечисляете их в алфавитном порядке (как в выводе ls
):
#!/bin/sh
i=0
for f in *.jpeg.jpg
do
mv "$f" "$(printf '%011d.jpeg.jpg' $i)"
i=$(expr $i + 1)
done