У меня неправильно названы файлы, которые не синхронизированы -1. Проблема в том, что мне нужно переименовать 1000 из них.
- DBGC180_805754
- DBGC180_805755
- DBGC180_805756
к
- DBGC180_805753
- DBGC180_805754
- DBGC180_805755
Я бы предпочел использовать скрипты bash или команды unix.
решение1
Вы можете сделать это:
# {smallestfilenum..largestfilenum}
for i in {805754..999999}; do
mv "DBGC180_$i" "DBGC180_$(($i-1))";
done
Попробуйте с небольшим числом (например, 805754..805758), чтобы убедиться, что это работает так, как вы ожидаете. Имейте в виду, что если файл с новым именем уже существует, он будет перезаписан.
решение2
- Переместите файлы, которые необходимо переименовать, в подкаталог (не меняя их имени).
- Переименуйте файлы из подкаталога в исходный каталог.
Есть две причины, по которым я рекомендую шаг 1, даже если без него можно обойтись:
- Если выполнение команды было прервано, вы можете продолжить с того места, где остановились, поскольку сразу видно, какие файлы уже переименованы, а какие нет.
- Вам не нужно беспокоиться о том, что вы выполните переименование в неправильном порядке и перезапишете один из существующих файлов.
Непроверенный фрагмент оболочки (полагающийся на тот факт, что уменьшаемое число никогда не имеет начальных нулей):
mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
number="${x##*_}"
mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement
Сзш, вы можете сделать это намного проще, благодаря егочисловой диапазон glob, еговстроенныйmv
что позволяет избежать ограничений на длину командной строки, и егофункция массового переименования на основе шаблона. В зш:
autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement
решение3
Итак, вы хотите переименовать DBGC180_805754
в DBGC180_805753
, ...55
в ...54
и т. д. Это проблема, которую я решу.
Сначала поместите этот скрипт куда-нибудь в свой PATH
, назовите его waltinator
.
#!/bin/bash
#step through the parameters
while [[ -n "$1" ]] ; do
oldname="$1"
# shift the arguments left
shift;
# strip off the fixed part of the old name
oldnum=${oldname##DBGC180_}
# decrement the number (this is what was wanted, right?)
newnum=$(( $oldnum - 1 ))
# build the new, improved filename
newname="DBGC180_$newnum"
if [[ -f "$newname" ]] ; then
printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
exit 1
fi
mv --no-clobber "$oldname" "$newname"
done
exit 0
Для следующего шага предположим, что скрипт находится в $HOME/bin/waltinator
, и у вас есть chmod +x $HOME/bin/waltinator
.
find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
sort | \
xargs $HOME/bin/waltinator
Находит find
файлы (в произвольном порядке), имена которых соответствуют шаблону shell glob " BDGC180_
с последующими 6 цифрами ( ). Поскольку нам нужен отсортированный список (переименование в до переименования [0-9]
было бы ошибкой ), мы запускаем вывод через . Затем мы используем , чтобы взять (отсортированный) список имен файлов, и создаем команду для передачи (отсортированного) списка имен файлов в . Прочтите, если вам нужно сократить список аргументов....97
...96
...96
find
sort
xargs
$HOME/bin/waltinator
man xargs
Если на то пошло, прочтите:
for page in bash mv find sort xargs ; do
man "$page"
done
решение4
Используйте rename
для замены каждого числа самим собой минус 1.
$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'
Примечания
rename
использует выражения Perl для переименования имен файлов.s
указывает, чтоrename
будут заменены некоторые или все имена файлов, соответствующие шаблону регулярного выражения.- Выражения подстановки Perl структурированы следующим образом.
s/PATTERN/REPLACEMENT/MODIFIER
\d{6}
это шаблон, которыйrename
будет искать и заменять. Это 6 десятичных цифр.$
— это переменная, хранящая совпавшую подстроку\d{6}
(в данном случае «подстрока» — это целое число).sprintf("%06",($&-1))
извлекает значение, хранящееся в$
, уменьшает его, затем возвращает это значение в качестве замены.%06
Для обработки начальных нулей.e
указано, чтоrename
замена оценивается так, как если бы это был оператор Perl, и в качестве текста замены используется возвращаемое значение.-v
заставляетrename
эхом отражать то, что он делает.
Если вы хотите быть в большей безопасности, используйте флаг -n
, который rename
просто скажет вам, что будет делать, а не сделает это.
Похоже, это работает только для уменьшения, поэтому будьте осторожны.