Справка со сценарием Bash - добавляющий порядковые номера

Я являюсь довольно новым для избиения сценариев и надежды, что кто-то выручит меня.

У меня есть папки, которые включают изображения, названные как так:

file_001.jpeg  
file_002.jpeg  
file_003.jpeg  

Я пытаюсь записать функцию удара, которая берет два аргумента и переименовывает файлы как так:

photo-argument1-argument2_001.jpeg  

например.

photo-christmas-2014_001.jpeg  

Вот то, что я имею:

function rename () {
  title="photo"
  h="-"
  u="_"
  new=$title$h$1$h$2$u
  for file in *.jpeg; do
    mv -v "$file" "$new"
  done
}

так выполнение rename birthday 2015 производит photo-birthday-2015_, например.

Существует всего одна проблема - как я добавляю числа к новому имени файла? Или вытаскивание существующих чисел в имени файла или генерация новых были бы прекрасны насколько результаты идут, но который является лучшим/легче путем, и как я пошел бы о том, чтобы заставлять это произойти?

6
задан 20 September 2016 в 17:37

4 ответа

Можно заставить удар значить Вас только путем сообщения этого, где запустить, как это:

$ n=0
$ echo $((++n))
1
$ echo $((++n))
2
$ echo $((++n))
3

можно использовать printf %03d для форматирования результата $((++n)) как 001 002 003 и 010, 011 и т.д., для более точной сортировки. Кроме того, нет никакого смысла установки - и _ как переменных, так как они не собираются варьироваться. Ваша функция могла быть похожей на это:

function rename () {
  title="photo"
  n=0
  for file in *.jpeg; do
   printf -v new "$title-$1-$2_%03d.jpeg" "$((++n))"
   mv -v -- "$file" "$new"
  done
}

, Который делает:

$ rename birthday 2015
'file_001.jpeg' -> 'photo-birthday-2015_001.jpeg'
'file_002.jpeg' -> 'photo-birthday-2015_002.jpeg'
'file_003.jpeg' -> 'photo-birthday-2015_003.jpeg'

, Но уже существует полезное rename команда в Ubuntu, таким образом, можно хотеть использовать другое имя :)

8
ответ дан 23 November 2019 в 07:20

Что я понял, Вы просто хотите добавить порядковые номера в конец. Я лично сделал бы это

 function rename () {
  count=1           #The first photo will get number 1 to the end
  title="photo"
  h="-"
  u="_"
  new=$title$h$1$h$2$u
  for file in *.jpeg; do
    if [ $count -lt 10 ]; then
        mv -v "$file" "${new}00$count" #numbers 1-9 will be like 001 002..
    elif [ $count -lt 100 ]; then
        mv -v "$file" "${new}0$count" #numbers 10-99 like 022 056 etc..
    else
        mv -v "$file" "$new$count"
    fi
    count=$[ $count + 1 ]      #count variable gets bigger by one 
  done
}

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

Hope, это помогает!

3
ответ дан 23 November 2019 в 07:20

Можно решить для себя, которые являются более легким путем.

Извлекающие старые числа

можно получить числа в имени файла с командой как grep:

number=$(egrep -o '[0-9]+' <<< "$file")

команда выше сохраняет любую последовательность цифр (подобранный шаблоном' [0-9] + ') в переменном файле (передал в grep до <<<) к переменному числу.

Генерирующие новые числа

можно попробовать что-то как ниже:

number=0 # initialize number to 0
for file in *.jpeg; do
    ... # do some stuff here
    ((number+=1)) # adds 1 to the variable number
done

Это генерирует число, запускающееся от 0 для каждого из Ваших файлов.

может быть полезно форматировать числа с фиксированной шириной (т.е. 001 вместо 1) для сортировки целей. В этом случае можно использовать printf для получения желаемого вывода:

number_formatted="$(printf "%03d" "$number")"

код выше форматов "12" как "012" и "321" как "321". "%03d" указывает формат (0 средств предварительно ожидают 0 к числу, 3 указывает 3 общих распечатанные цифры, включая любой 0s).

1
ответ дан 23 November 2019 в 07:20

Немного длинная но применимая альтернатива Python. Принятие Вашего именования согласовывается с тем, что Вы имеете в примере, Вы могли использовать эту функцию в Вашем ~/.bashrc. (Помните "\" символы. Не должно быть никакого пространства после затем, только новая строка),

rename_photos()
{
    python -c 'import os,re,sys; \
    [ os.rename(f, "photo_"+sys.argv[1]+\
      "_"+sys.argv[2]+"_"+re.split("[_.]",f)[-2]+\
      "."+re.split("[_.]",f)[-1])  \
      for f in os.listdir(".") \
    ]' "$1" "$2"
}

И звоните как

rename_photos arg1 arg2

Принятие Вашего именования последовательно, что это делает имя файла разделений в части в"." и "_" и переименовывает их через os.rename function

Например:

$ ls
file_001.jpeg  file_002.jpeg  file_003.jpeg
$ rename_photos birthday 2016
$ ls
photo_birthday_2016_001.jpeg  photo_birthday_2016_002.jpeg  photo_birthday_2016_003.jpeg

Версия сценария

Не делая это чрезмерно сложным, вот маленький сценарий, который делает ту же функцию. Существует много комментария для объяснения, что делает каждая часть. Сам сценарий должен быть сохранен в одном из каталогов, которые принадлежат Вашего $PATH переменная, например, в Вашем ~/bin папка. Иначе это выполняет точно ту же функцию (в дополнение к печати новых имен файлов)

#!/usr/bin/env python
import os
import re
import sys

# The operates on all files in the current working
# directory, so you would have to cd to your folder
# and run script there. 
for item in os.listdir("."):

    # We don't wanna rename the script itself ( just in case ) and
    # we don't
    if os.path.join("./" + item) != __file__ and \
       os.path.isfile("./" + item):
           title="photo_"

           # Old name can be split into parts using _ and . as 
           # separators, so we only take items between those as one.
           # The last item (-1) is extension, and the one
           # before extension is number
           old_name = re.split("[_.]",item)
           new_name = sys.argv[1] + sys.argv[2] + "_" \
                      + old_name[-2] + "." + old_name[-1]

           print(new_name)
           os.rename(item,new_name)
3
ответ дан 23 November 2019 в 07:20

Другие вопросы по тегам:

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