Как удалить конечные символы в именах файлов в Bash?

13

У меня есть куча медиа-файлов, как показано ниже:

tvshow.s01e11]Bloodlines.avi
tvshow.s01e12]suffer.avi
tvshow.s01e13]NotMe.avi

Я хотел бы переименовать их в

tvshow.s01e11.avi
tvshow.s01e12.avi
tvshow.s01e13.avi

Я пытался использовать переименование, но, очевидно, я неправильно понял синтаксис, потому что он не работает.

Widgeteye
источник
Если вы когда-нибудь захотите сделать это в графическом интерфейсе, krename это прекрасно. Он имеет всевозможные мощные опции и показывает вам, что он собирается сделать до того, как он это сделает. Вы даже можете использовать его для тестирования шаблонов, которые вы можете использовать в bash позже.
Joe

Ответы:

9

Это переименует файлы. Вам нужна \ w * для обозначения любого количества буквенно-цифровых символов.

rename 's/\]\w*//' *

Ссылка: http://www.troubleshooters.com/codecorn/littperl/perlreg.htm#UsingSimpleWildcards

LvxOne
источник
5
Обратите внимание, что это требует Perl rename утилита, а не один с таким же именем из util-linux , Увидеть Вот а также Вот
ilkkachu
14

В оболочке можно сделать просто:

for x in *]*.avi ; do 
    mv -i "$x" "${x%]*.avi}.avi"
done

Оболочка может создать список имен файлов с помощью обычного глобуса, и ${var%pattern} удаляет (самый короткий) образец соответствия с конца строки в переменной var, Поскольку окончательное расширение всегда .aviЯ просто удалил его с рисунком и добавил обратно. С кавычками это должно работать и с именами файлов, содержащими пробелы, например Fancy Name for a Show.s01e01]Asdf.avi

ilkkachu
источник
@NoviceC шаблон extglob не был плохой идеей. На самом деле, что-то вроде ${x/]*([^.])} должен сделать, он удаляет скобку и любое количество не точек. (хотя происходит сбой, если есть другие скобки или точки, так как он не заблокирован до конца строки)
ilkkachu
Неплохо подмечено. Но я действительно слишком усложнил проблему, когда мне следовало пойти с ${x/]*.avi} и просто добавил .avi как ты. Но я также был недоволен тем, как пробелы в имени будут ломаться (`find . -name '*]*.avi'`), Я был рад предоставить ограниченный стандартный метод команд Unix, так как переименование - нет, но это выбивает меня из воды.
Novice C
2

Это все виды непрактично - другие ответы гораздо быстрее и короче - но ...

Вы можете использовать PowerShell! Microsoft с открытым исходным кодом это недавно и сделал это кроссплатформенным. Инструкции по загрузке и установке для вашей ОС см. В разделе раздел «Получить PowerShell» ,

Как только вы установите его, вы можете использовать этот краткий скрипт:

Get-ChildItem -File '*]*.avi' | ForEach-Object {
    Rename-Item $_ -NewName (($_.Name -Split ']')[0] + '.avi')
}

По сути, он проходит через каждый объект в текущем каталоге, который соответствует файлу *]*.avi, получает деталь перед кронштейном, прихватывает .avi обратно на него, и назначает его в качестве нового имени.

Чтобы запустить его прямо из Bash, используйте этот однолинейный полугольфорный:

powershell -command $'gci -File \'*]*.avi\'|%{rename-item $_ -NewName (($_.Name -Split \']\')[0]+\'.avi\')}'

Цитата избегает любезно этот ответ переполнения стека ,

(Протестировано в Bash на Ubuntu для Windows. Вероятно, есть гораздо более короткий способ сделать это с PowerShell, но я хотел показать что-то понятное людям, не знающим регулярные выражения.)

Ben N
источник
Рубе Голдберг был бы горд! Регексы - это настоящая PITA для изучения, но они стоят этого много раз - даже на элементарном уровне, на котором я могу их использовать.
Joe
1

У Debian есть пакет, который называется MMV который также может быть доступен в других дистрибутивах и должен быть достаточно простым для компиляции из источника, если нет Это позволяет вам написать это:

mmv '*]*.avi' '#1.avi'

Вы можете прочитать Страница справочника Ubuntu для этой команды для более подробной информации.

MvG
источник
0

Это будет искать шаблон и заменить текст с помощью sed.

 $sed 's/\(.*]\)[a-zA-z0-9].*\(.avi\)/\1\2/' filename
Tejender Mohan
источник