Рекурсивно удалить дату и время из имен файлов

Я могу рассказать вам о своем опыте на данный момент. У меня есть Acer Aspire V5 Nitro с i5 и nvidia 940m. Я использую Fedora 25 с драйвером nouveau по умолчанию. Возможно, этому модерну не хватает производительности, но он очень хорошо справляется с динамическими переключениями. В основном у меня выключено энергосбережение, даже hdmi работает.

1
27.05.2017, 18:37
5 ответов

Если вы действительно хотите сделать это "с bash", то

find . -name '*.wcr' -execdir bash -c '
  shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +

Это зависит от расширенного glob +([ 0-9-]), который соответствует одному или нескольким вхождениям символов в наборе [0-9-]

Вы можете сделать замену более конкретной, например ${f/_2017+([0-9-])_/_}, если простое сопоставление цифр и тире слишком распространено.

Примечание: удалите эхо , как только вы убедитесь, что он делает то, что вам нужно.

1
27.01.2020, 23:19

Использование команды perl rename (любой вариант, но не util-linux rename):

find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +
1
27.01.2020, 23:19

Если файлы всегда имеют один уровень каталога в глубину, вы можете выполнить итерацию по ним с помощью чего-то вроде для x в */*_20*_*. Какой шаблон использовать, зависит от того, какие другие файлы могут присутствовать, которые вы не хотите переименовывать. Шаблон, который я только что дал, предполагает, что дата начинается с 20 и что все файлы, имя которых содержит _20 и еще один знак подчёркивания после этого, должны быть переименованы.

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

for old_name in ./*/*_20_*_*; do
  base=${old_name##*/}        # remove the directory part
  prefix=${base%%_20*}        # remove everything from _20
  suffix=${base#*_20}         # remove everything up to _20
  suffix=${suffix#*_}         # ... then everything before the first remaining _
  mv "$old_name" "${old_name%/*}/${prefix}_${suffix}"
done

Если файлы имеют разную глубину, в bash ≥4.3 вы можете запустить shopt -s globstar, затем для x в **/*_20*_*; …. Шаблон ** соответствует любой глубине каталога, если globstar включен. Это также работает в bash 4.0–4.2 с оговоркой, что он также проходит через символические ссылки на каталоги.Это также работает в zsh и ksh, без оговорок, из коробки в zsh и с set -o globstar в ksh.

0
27.01.2020, 23:19
for i in ./*/*; do
  j=`echo "$i" | cut -d'_' -f1-2,4-`
  mv "$i" "$j"
done

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

1
27.01.2020, 23:19

Используйте команды find + prename (Perl rename):

find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +

Чтобы просмотреть результат prename без действия, добавьте опцию -n (печатать имена файлов, которые нужно переименовать, но не переименовывать):

man rename

  • [0-9]{4}-[0-9]{2}-[0-9]{2} - шаблон, указывающий на дату-подобную подстроку ( например 2017-05-26)
1
27.01.2020, 23:19

Теги

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