Сочетание клавиш Shell / Bash для массового переименования файлов в папке - PullRequest
49 голосов
/ 07 декабря 2011

Есть ли в Shell / Bash ярлык, который может переименовать все файлы в папке на основе регулярных выражений или некоторых других критериев.То, что я ищу здесь, находится в моих папках с документами, в которых, скажем, 100 текстовых файлов со следующим соглашением об именах:

<longdocumentidentifier>-doc-<counter>.txt.

Мне нужно переименовать все файлы с вышеуказанным соглашением, чтобы они просто:

doc-<counter>.txt

Есть ли одна строчка, которая может помочь мне с вышеуказанным?

Ответы [ 8 ]

93 голосов
/ 07 декабря 2011

Я бы предложил что-то вроде этого:

for i in *-doc-*.txt; do mv $i ${i/*-doc-/doc-}; done

${i/*-doc-/doc-} заменяет первое вхождение *-doc- на doc-.

Если вам нужно сделать более одной замены (см. Комментарий № 1), вам нужно использовать вариант ${var//Pattern/Replacement}. Если вам нужно заменить начало имени, вам нужно использовать ${var/#Pattern/Replacement}, если вам нужно заменить конец (т. Е. Расширение), вам нужно использовать форму ${var/%Pattern/Replacement}.

Подробнее см. http://tldp.org/LDP/abs/html/parameter-substitution.html#EXPREPL1

21 голосов
/ 07 декабря 2011

Если у вас есть rename, тогда rename 's/^.*-doc-/doc-/' *.txt должен сделать трюк.

12 голосов
/ 07 декабря 2011

Существует prename, что позволяет использовать REGEX:

prename 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Используйте опцию -n для имитации:

prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Примечание: Это поставляется как rename во многих дистрибутивах Linux, но не во всех - поэтому я использую каноническое имя для утилиты, поставляемой с Perl.

8 голосов
/ 07 декабря 2011

Команда переименования, встроенная в большинство Linux, например, сделает это легко.

Лично я тоже предпочитаю регулярные выражения, поэтому я очень и очень долго носил этот скриптчитай: с конца 80-х или начала 90-х):

#!/usr/bin/perl

($op = shift) || die "Usage: $0 expr [files]]\n";

if(!@ARGV)
  {
  @ARGV = <STDIN>;
  chop(@ARGV);
  }

for (@ARGV)
  {
  $was = $_;
  eval $op;
  die $@ if $@;

  if ($was ne $_)
    {
    print "rename($was,$_)\n";
    rename($was,$_);
    }
  }

Что, при установке, позволяет делать такие вещи:

script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt
5 голосов
/ 22 августа 2014

Если вы хотите перейти в подкаталоги, есть также:

find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv

В системе, которая автоматически поддерживает расширенные регулярные выражения, вы можете оставить -E.

Преимущества:

  • рекурсивно в подкаталоги
  • вы можете контролировать максимальную глубину рекурсии
  • вы можете переименовывать файлы и / или каталоги (-type f | d)

Недостатки:

  • немного более сложные регулярные выражения, потому что вам нужно убрать путь, чтобы добраться до имени файла

(ответ изменен с здесь )

4 голосов
/ 08 февраля 2013
mmv "*-doc-*" "doc-#2"

команда mmv означает «массовый ход»

3 голосов
/ 15 октября 2015

Если вы не против внешнего инструмента, вот один из них: rnm ( веб-страница )

Для вашей конкретной проблемы команда будет:

rnm -rs '/.*-doc-/doc-/' *.txt

Или

rnm -rs '/.*-(doc-.*\.txt)/\1/' *.txt

Вы можете найти больше примеров / документов здесь .

0 голосов
/ 13 июля 2017

найти.имя * scssxargs -L1 -I {} echo {} {} |sed 's / css.scss $ / scss /' |xargs -L1 mv

например, если у вас есть куча файлов, заканчивающихся на «.css.scss», и вы хотите переименовать их, чтобы они заканчивались просто «.scss» (т.е. удалите .cssчасть)

настроить регулярное выражение и найти аргументы для ваших нужд

...