Замена чисел в имени файла в unix (BASH)

#bash #file #for-loop #rename

#bash #файл #for-цикл #переименовать

Вопрос:

У меня есть несколько файлов примерно 150, и их имена не соответствуют требованиям поставщика. примеры имен файлов:

 company_red001.p12 
company_red002.p12
.
.
.
.
company_red150.p12
 

Мне нужно переименовать все файлы так, чтобы к каждому числу последовательно добавлялось 24, и чтобы не было предшествующих нулей, и чтобы компонент company_ был удален.

 red25.p12
red26.p12
red27.p12
.
.
.
red150.p12
 

Я использовал цикл for в bash для удаления компонента company_, но хотел бы что-то, что выполняет все изменения одновременно, поскольку я должен выполнить это в любой момент. уведомление.

пример:

 #!/bin/bash

n = 24

for file in company_red*

do

  new_name=$file$n
  n=$(($ 1))
  mv -i $file $new_name

done
 

пример 2

 #!/bin/bash

for f in company_red*

do mv "$f" "${f/company_red/red}";

done
 

Комментарии:

1. Добро пожаловать в Stack Overflow.. I have used a for loop in.. — Пожалуйста, предоставьте примеры кода, о которых идет речь, чтобы показать хотя бы некоторые усилия с вашей стороны 🙂

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

3. Спасибо всем, проблема решена.

Ответ №1:

Скорее всего, это может быть хорошо 🙂

 # printf is used to emulate a lot of files
for f in $( printf "company_redd.p12n" {1..150} )
do
    # get the filename
    n="$f"
    # remove extension
    n="${n%.*}"
    # remove leading letters
    n="${n##*[[:alpha:]]}"
    # add 24, 10# is used to consider the 10-based number
    n="$(( 10#$n   24 ))"
    # construct new filename
    g="red${n}.p12"
    echo mv "$f" "$g"
done
 

И это можно было бы немного упростить

 for f in $( printf "company_redd.p12n" {1..150} )
do
    # take the number from the specific, fixed position
    n="${f:11:3}"
    # everything below is the same as in the previous example
    n="$(( 10#$n   24 ))"
    g="red${n}.p12"
    echo mv "$f" "$g"
done
 

И, наконец, это можно было бы упростить еще дважды — просто отказаться от использования $n и $g :

 for f in $( printf "company_redd.p12n" {1..150} )
do
    echo mv "$f" "red$(( 10#${f:11:3}   24 )).p12"
done
 

Но это может усложнить понимание и поддержку кода.

Ответ №2:

Выполните:

 for file in *.p12; do 
    name=${file#*_}  ## Extracts the portion after `_` from filename, save as variable "name"
    pre=${name%.*}  ## Extracts the portion before extension, save as "pre"
    num=${pre##*[[:alpha:]]}  ## Extracts number from variable "pre"
    pre=${pre%%[0-9]*}  ## Extracts the alphabetic portion from variable "pre"
    suf=${name##*.}  ## Extracts the extension from variable "name"
        echo mv -i "$file" "${pre}""$(printf '%d' $((10#$num 24)))"."${suf}"  ## Doing arithmetic expansion for addition, and necessary formatting to get desired name
done
 

Выводит:

 mv -i company_red001.p12 red25.p12
mv -i company_red002.p12 red26.p12
 

Вышесказанное является пробным, удалите echo , если вас устраивает выполняемое переименование.:

 for file in *.p12; do 
    name=${file#*_}
    pre=${name%.*}
    num=${pre##*[[:alpha:]]}
    pre=${pre%%[0-9]*}
    suf=${name##*.}
        mv -i "$file" "${pre}""$(printf '%d' $((10#$num 24)))"."${suf}"
done