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

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

У меня есть папка, которая содержит папки, которые содержат файлы вида

resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr

Я хочу удалить дату и время для каждого из них, поэтому в этом случае получим

resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr

Как это сделать в bash?

решение1

Если вы действительно хотите это сделать"с башем", затем

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

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

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

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

решение2

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

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)

решение3

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

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

решение4

Если файлы всегда находятся на одном уровне каталога, то вы можете перебрать их с помощью чего-то вроде for x in */*_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запустить for x in **/*_20*_*; ….шаблон**соответствует любой глубине каталога, если globstarвключено. Это также работает в bash 4.0–4.2 с оговоркой, что он также проходит по символическим ссылкам на каталоги. Это также работает в zsh и ksh, без оговорки, из коробки в zsh и с set -o globstarв ksh.

Связанный контент