Скажите, что у меня есть диапазон названных файлов: "blah-10-blah", "blah-11-blah" и т.д.... до "blah-30-blah".
Я хотел бы изменить имена на "blah-20-blah", "blah-21-blah" и т.д.... до "blah-40-blah".
Существует ли способ сделать это в терминале?
Можно сделать:
#!/bin/bash
files=( blah-??-blah )
for ((i=${#files[@]}-1; i>=0; i--)); do
first="${files[$i]%%-*}"
num="$(grep -o '[0-9]\+' <<<"${files[$i]}")"
last="${files##*-}"
echo mv "$first-$num-$last" "$first-$((num+10))-$last"
done
, Если Вы удовлетворены всем, добавьте | bash
в конце для разрешения mv
, операция происходит.
Мы поместили соответствующие имена файлов в массив files
Затем, мы выполнили итерации по элементам массива от конца, т.е. от в последний раз до первого
first
будет иметь первую часть имени файла, т.е. часть до первого -
last
будет иметь последнюю часть имени файла т.е. часть после того, как в последний раз -
num
будет иметь число промежуточным два -
mv "$first-$num-$last" "$first-$((num+10))-$last"
, сделает переименовать операцию соответственно
Пример:
$ ls -1
blah-10-blah
blah-11-blah
blah-12-blah
blah-13-blah
blah-14-blah
blah-15-blah
blah-16-blah
blah-17-blah
blah-18-blah
blah-19-blah
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-foo-1
blah-foo-2
$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}"; \
echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done
mv blah-30-blah blah-40-blah
mv blah-29-blah blah-39-blah
mv blah-28-blah blah-38-blah
mv blah-27-blah blah-37-blah
mv blah-26-blah blah-36-blah
mv blah-25-blah blah-35-blah
mv blah-24-blah blah-34-blah
mv blah-23-blah blah-33-blah
mv blah-22-blah blah-32-blah
mv blah-21-blah blah-31-blah
mv blah-20-blah blah-30-blah
mv blah-19-blah blah-29-blah
mv blah-18-blah blah-28-blah
mv blah-17-blah blah-27-blah
mv blah-16-blah blah-26-blah
mv blah-15-blah blah-25-blah
mv blah-14-blah blah-24-blah
mv blah-13-blah blah-23-blah
mv blah-12-blah blah-22-blah
mv blah-11-blah blah-21-blah
mv blah-10-blah blah-20-blah
$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}";\
echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done | bash
$ ls -1
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-31-blah
blah-32-blah
blah-33-blah
blah-34-blah
blah-35-blah
blah-36-blah
blah-37-blah
blah-38-blah
blah-39-blah
blah-40-blah
blah-foo-1
blah-foo-2
Важно обработать файлы в обратном числовом порядке, иначе задача перестанет работать из-за уже существующих файлов с целевым именем файла:
find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
find . -maxdepth 1 -type f -name 'blah-??-blah' -print0
: печатает РАЗДЕЛЕННЫЙ ОТ ПУСТОГО УКАЗАТЕЛЯ список файлов в текущем рабочем каталоге, соответствующем globbing шаблону blah-??-blah
; sort -zr
: сортирует список в обратном числовом порядке; xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
: переименовывает файлы, заменяющие этими первыми двумя цифрами после тире с соответствующим значением, увеличенным 10; % tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah
0 directories, 21 files
% find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
% tree
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah
0 directories, 21 files
При использовании Zsh, задача может быть в большой степени упрощена, поскольку Zsh позволяет разворачивать имена файлов в обратном числовом порядке:
rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah
0 directories, 21 files
% rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah
0 directories, 21 files
Основная идея об этом подходе состоит в том, чтобы бросить все файлы во временный каталог "корзины", и затем выбрать их один за другим, создать новое имя и попятиться с новым именем в исходный каталог.
рев сценария берет отдельный аргумент (1$), который является каталогом, где файлы, которые Вы хотите переименовать, расположены.
Демонстрация
xieerqi:$ ls testdir
blah-10-blah blah-20-blah blah-30-blah blah-40-blah
xieerqi:$ cat testdir/*
I am file 10
I am file 20
I am file 30
I am file 40
xieerqi:$ ./incrementNames.sh testdir
blah-10-blah ../blah-20-blah
blah-20-blah ../blah-30-blah
blah-30-blah ../blah-40-blah
blah-40-blah ../blah-50-blah
xieerqi:$ ls testdir
blah-20-blah blah-30-blah blah-40-blah blah-50-blah TMP/
xieerqi:$ cat testdir/blah
blah-20-blah blah-30-blah blah-40-blah blah-50-blah
xieerqi:$ cat testdir/blah-20-blah
I am file 10
xieerqi:$ cat testdir/blah-30-blah
I am file 20
Ограничение Сценария
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: incrementNames.sh /path/to/dir" && exit
fi
# navigate to target directory
# create temporary directory
cd "$1"
mkdir TMP
# move everything to TMP directory
find . -maxdepth 1 -type f -iname "*-*" -exec mv -t TMP {} \+
# drop down to TMP directory pick filesback into the directory , and rename them as we go
cd TMP
find . -maxdepth 1 -type f -iname "*-*" -printf "%f\n" | sort | while IFS= read FILENAME
do
NEW="$( awk -F '-' '{print $1FS$2+10FS$3 }' <<< "$FILENAME")"
echo "$FILENAME" "../$NEW"
mv "$FILENAME" ../"$NEW"
done
Этот сценарий специально для файлов после шаблона text-number-text
, или по крайней мере text-number
скороговорка. Это работа привычки для других