rename (1) -подобный скрипт в Perl, но для копирования файлов?

Итак, это rename(1) Perl. Это точно соответствует моей задаче, за исключением того, что мне нужно это в основном cp файлах вместо mv .

Как это сделать? У меня довольно много правил переименования, все они выражены компактно в s|/foodir/|/|;s|/bardir/|/| формы, а затем несколько строк шаблонов файлов, которые мне нужно скопировать.

Это выглядит примерно так:

 rename -v 's|/pars/|/|; s|/fts/|/|; s|innobase/include|include|' \ storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \ storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \ storage/innobase/include/fts0[bt]lex.h 

Я подозреваю, что короткий фрагмент Perl будет сиять в этом, но я не очень много говорю о Perl.

Любая помощь?

Это работа для человека . pax – стандартная команда POSIX; некоторые дистрибутивы Linux опускают его из установки по умолчанию, поэтому вам может потребоваться установить пакет явно. Вы не получаете полную мощность Perl, просто заменяете регулярное выражение, но это достаточно хорошо для вашего случая использования.

 pax -rw -pe -s'|/pars/|/|' -s'|/fts/|/|' -s'|innobase/include|include|' … 

Если вы хотите что-то более мощное, zmv zsh . На этом сайте много примеров , например, Traverse, копировать и преобразовывать имена файлов , как переименовывать файлы во время копирования?

Философия Unix: один инструмент делает одно (очень хорошо), а затем объединяет инструменты.

Я предлагаю вам использовать инструменты, которые вы знаете. Инструменты, которые имеют все функции и параметры, которые вам нужны, и знать / мастер уже.

Итак, используйте cp , rsync , scp или что-то еще, а затем используйте свою любимую команду rename .

Хорошо, поэтому мне удалось уйти с простым старым sed .

 ls -1 \ storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \ storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \ storage/innobase/include/fts0[bt]lex.h \ | sed -re 'h; s|/pars/|/|; s|/fts/|/|; s|innobase/include|include|; H; x; s|\n| |' \ | xargs -L1 cp -v \ ; 

Сценарий sed не настолько тривиальен, поэтому позвольте мне объяснить шаг за шагом (для будущего меня):

  • h копирует текущую строку («пространство образца») в регистр («пространство удержания»);
  • каждый s редактирует пространство шаблонов, как обычно, пробел не изменяется;
  • H присоединяет теперь отредактированную строку к регистру удержания, которая заканчивается тем, что удерживает две строки, старое имя файла и новое, со встроенными \n символами, конечно;
  • x обменивает пространство удержания с пространством шаблонов, эффективно загружая старую новую пару из регистра hold;
  • s|\n| | выравнивает две линии в одну, разделяя их пространством;
  • и, наконец, неявный p (из вызова sed без -n ) выводит результат.

В целом, трубопровод работает следующим образом:

  • ls -1 расширяет все глобусы в имена файлов реальных существующих файлов и печатает их по одной строке;
  • sed превращает это в "$old_filename $new_filename" , снова один файл в строке;
  • xargs -L1 вызывает cp -v $old_filename $new_filename в каждой строке.

Это оно!