Переименовать несколько файлов, чтобы уменьшить номер в имени файла?

Я не знаю, к какой системе обращаться конкретно, но если ваша использует resolvconf , попробуйте следующее от имени пользователя root ( su - или sudo -i ]):

echo 'nameserver 10.165.74.2' >> /etc/resolvconf/resolv.conf.d/head
resolvconf -u

В этом файле есть предупреждение о том, что изменения, внесенные вручную, будут перезаписаны; но в контексте сообщение относится к /etc/resolv.conf , а не к /etc/resolvconf/resolv.conf.d/head .

Это должно поместить желаемый сервер имен первым в списке. Конечно, если это работает в вашей операционной системе, то 10.165.74.2 можно удалить из NetworkManager.

Локальный преобразователь, dnsmasq , также является отличным средством продвижения вперед. Используя dnsmasq , можно использовать гораздо больший контроль над DNS и DHCP. Например, в этом сценарии dnsmasq может запрашивать конкретный сервер имен на основе указанного доменного имени с опцией server . См. Фрагмент из dnsmasq.conf , который может иметь отношение к вашей цели ниже.

# Add other name servers here, with domain specs if they are for
# non-public domains.
server=/our-company-domain.com/10.165.74.2

Обновление

Спасибо за упоминание операционной системы. В CentOS 7 существует множество методов. В графическом интерфейсе щелкните Приложения> Системные инструменты> Настройки> Сеть. Выберите соединение для настройки.

CentOS 7 NetworkManager - Configure Connection

Отключите автоматический DNS и укажите серверы имен. Примените конфигурацию.

CentOS 7 NetworkManager - Apply Static DNS Settings

В следующий раз, когда NetworkManager запустит это соединение, он запишет пользовательские значения. (Во время тестирования я выключил и снова включил сеть, потому что у меня было два сетевых подключения.)

Согласно документации ,

  1. Простой текстовый пользовательский интерфейс на основе curses (TUI) для NetworkManager , nmtui, доступен.
  2. Инструмент командной строки, nmcli, позволяет пользователям и сценариям взаимодействовать с NetworkManager. Обратите внимание, что nmcli может использоваться в системах без графического интерфейса пользователя, таких как серверы, для управления всеми аспектами NetworkManager. Это наравне с инструментами графического интерфейса.

В частности, очень хорошо выглядела документация nmcli .

2
29.09.2016, 10:24
7 ответов
  1. Переместите файлы для переименования в подкаталог (не меняя их имени).
  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

С zsh вы можете сделать это намного проще, благодаря числовому диапазону glob, встроенному mv который позволяет избежать ограничений длины командной строки, и основанной на шаблонах функции массового переименования. В zsh:

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
27.01.2020, 22:04

Итак, вы хотите переименовать DBGC180_805754 в DBGC180_805753 , ... 55 С по ... 54 и так далее. Я решу эту проблему.

Сначала поместите этот скрипт где-нибудь в ПУТЬ , назовите его 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 находит файлы (в произвольном порядке), имена которых соответствуют шаблону оболочки оболочки " 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   
0
27.01.2020, 22:04

Используйте awk для создания полностью развернутого сценария переименования:

find . -name "DBGC180_*" |sort |awk -F "_" '{print "mv -i "$0" "$1"_"$2-1}' >/tmp/rename.sh

Вы можете просмотреть сценарий перед выполнением. Это уникальная особенность данного решения. Затем выполните его:

sh -e -x /tmp/rename.sh

Примечания

  • вы можете улучшить шаблон поиска, вопрос не на 100% ясен, какие файлы следует переименовать.
  • sort важен, чтобы не перезаписывать существующие файлы
  • mv option -i делает особо безопасным никогда не перезаписывать файлы
  • sh option -e - прервать скрипт в случае ошибки
  • sh option -x печатает трассировку, чтобы увидеть, что было сделано до сих пор, в случае прерывания скрипта (для восстановления возможный). Вы также можете использовать вместо него mv -v , если это поддерживается.
-1
27.01.2020, 22:04

Если вы хотите переименовать эти конкретные файлы, то вот решение (статическое). Сначала переименуйте и переместите эти файлы в подкаталог. Оттуда переместите эти файлы в текущий каталог

#!/bin/bash
# rename.sh

#make a subdirectory
mkdir -p subDir

#move all files to subdirectory with rename
for i in {5754..6754}; do
   mv "DBGC180_80$i" "./subDir/DBGC180_80$(($i-1))";
done

#move all files from subdirectory to current directory
for j in {5754..6754}; do
    mv "./subDir/DBGC180_80$(($j-1))" "./DBGC180_80$(($j-1))"
done

#remove subdirectory
rmdir subDir

Эту программу можно изменить, сделав ее общей (динамической)

0
27.01.2020, 22:04

Вы можете сделать это:

# {smallestfilenum..largestfilenum}

for i in {805754..999999}; do 
   mv "DBGC180_$i" "DBGC180_$(($i-1))";
done

Попробуйте с небольшим числом (скажем, 805754..805758), чтобы убедиться, что он работает так, как вы ожидаете. Имейте в виду, что если файл с новым именем уже существует, он будет перезаписан.

3
27.01.2020, 22:04

Вау, это оказалось сложнее, чем я ожидал.

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

Я написал эту команду, чтобы она была достаточно устойчивой к сбоям. Обратите внимание, что мы явно исключаем файлы, в которых число начинается с 0; если у вас есть такие файлы, оставьте комментарий, и я добавлю команду для работы с ними.

find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9]' -exec sh -c 'for f; do mv -i "$f" "${f%_*}_$((${f##*_}-1)).decremented"; done' find-sh-decrement {} + && find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9].decremented' -exec sh -c 'for f; do mv -i "$f" "${f%.decremented}"; done' find-sh-remove-prefix {} +

С переносом строк (все еще можно скопировать и вставить):

find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec sh -c 'for f;
    do mv -i "$f" "${f%_*}_$((${f##*_}-1)).decremented";
    done' find-sh-decrement {} + &&
  find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9].decremented' \
  -exec sh -c 'for f;
    do mv -i "$f" "${f%.decremented}";
    done' find-sh-remove-prefix {} +

Объяснение частей (для этого может потребоваться некоторая очистка форматирования):

##### Recursively find regular files in the current directory...
find . -type f
##### whose name matches this exact pattern...
-name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9]'
##### and run the following shell script...
-exec sh -c
##### (shell script: ) for every file given as an argument...
'for f;
##### rename the file, prompting for confirmation for any overwrites...
do mv -i
##### from the original file name...
"$f"
##### to the file name decremented by 1, with '.decremented' afterward...
"${f%_*}_$((${f##*_}-1)).decremented";
##### (End of shell script)
done'
##### on as many found files as possible at once,
##### using the name "find-sh-decrement" for error reporting.
find-sh-decrement {} +
##### If that completes successfully...
&&
##### Pass through again and remove the ".decremented" prefix.
find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9].decremented' -exec sh -c 'for f; do mv -i "$f" "${f%.decremented}"; done' find-sh-remove-prefix {} +

Результаты теста:

$ ls
DBGC180_805754  DBGC180_805755  DBGC180_805756
$ cat DBGC180_805754
This file started as DBGC180_805754
$ cat DBGC180_805755 
This file started as DBGC180_805755
$ cat DBGC180_805756
This file started as DBGC180_805756
$ find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9]' -exec sh -c 'for f; do mv -i "$f" "${f%_*}_$((${f##*_}-1)).decremented"; done' find-sh-decrement {} + && find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9].decremented' -exec sh -c 'for f; do mv -i "$f" "${f%.decremented}"; done' find-sh-remove-prefix {} +
$ ls
DBGC180_805753  DBGC180_805754  DBGC180_805755
$ cat DBGC180_805753
This file started as DBGC180_805754
$ cat DBGC180_805754
This file started as DBGC180_805755
$ cat DBGC180_805755
This file started as DBGC180_805756
$ 

Для дополнительной безопасности запустите первый find и проверьте результаты самостоятельно, прежде чем запускать вторую команду для удаления суффикса .decremented .

Запустите это:

find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec sh -c 'for f;
    do mv -i "$f" "${f%_*}_$((${f##*_}-1)).decremented";
    done' find-sh-decrement {} +

Затем проверьте результаты и , затем запустите это:

find . -type f -name 'DBGC180_[1-9][0-9][0-9][0-9][0-9][0-9].decremented' \
  -exec sh -c 'for f;
    do mv -i "$f" "${f%.decremented}";
    done' find-sh-remove-prefix {} +
-1
27.01.2020, 22:04

Используйте 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}(, в данном случае «подстрока» — это int ).
  • sprintf("%06",($&-1))извлекает значение, хранящееся в $, уменьшает его на единицу, а затем возвращает это значение в качестве замены. %06предназначен для обработки ведущих нулей.
  • eуказал, что renameоценивает замену, как если бы это был оператор Perl, и использует возвращаемое значение в качестве текста замены.
  • -vзаставляет renameповторять то, что он делает.

Если вы хотите быть в большей безопасности, используйте флаг -n, чтобы renameтолько сообщал вам, что он будет делать, вместо того, чтобы делать это.

Похоже, что это работает только для уменьшения, поэтому обращайтесь с этим осторожно.

0
27.01.2020, 22:04

Теги

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