Подтвердить что ты не робот

Переименование большого количества файлов в Linux по шаблону

Я пытаюсь сделать три вещи с помощью команды mv, но не уверен, что это возможно? Возможно, потребуется script. не уверен, как это записать. Все файлы находятся в одной папке.

1) Файлы, заканчивающиеся на v9.zip, должны быть просто .zip(удалено v9)

2) Файлы, содержащие _, должны быть -

3) Файлы с буквой верхнего порядка рядом с строчной буквой (или строчными буквами рядом с верхним регистром) должны иметь пробел между ними. Таким образом MoveOverNow будет перемещаться сейчас, а ruNaway будет недоступен [A-Z] [a-z] или [a-z] [A-Z] становится [A-Z] [a-z] и [a-z] [A-Z]

4b9b3361

Ответ 1

Мое любимое решение мое собственное переименование script. Самый простой пример, который отображает ваши проблемы:

% rename 's/_/-/g' *
% rename 's/(\p{Lower})(\p{Upper})/$1 $2/g' *

Хотя я действительно ненавижу пробелы в своих именах файлов, особенно вертикальные пробелы:

 % rename 's/\s//g' *
 % rename 's/\v//g' *

et cetera. Его основано на script на стене Ларри, но расширено с вариантами, как в:

usage: /home/tchrist/scripts/rename [-ifqI0vnml] [-F file] perlexpr [files]
    -i          ask about clobbering existent files
    -f          force clobbers without inquiring
    -q          quietly skip clobbers without inquiring
    -I          ask about all changes
    -0          read null-terminated filenames
    -v          verbosely says what its doing 
    -V          verbosely says what its doing but with newlines between old and new filenames
    -n          don't really do it
    -m          to always rename
    -l          to always symlink
    -F path     read filelist to change from magic path(s)

Как вы видите, он может изменять не только имена файлов, но и где символические ссылки указывают на использование одного и того же шаблона. Вам не нужно использовать шаблон s///, хотя часто это делается.

другие инструменты в этом каталоге в основном предназначены для работы в Unicode, из которых есть некоторые супер-полезные.

Ответ 2

Здесь есть команда rename, предоставляемая большинством дистрибутивов на основе Debian/Ubuntu, написанная Робин Баркером на основе исходного кода Ларри Уэлла примерно с 1998 года (!).

Здесь выдержка из документации:

  "rename" renames the filenames supplied according to the rule specified as the first argument.  The perlexpr argument is a Perl expression which is expected to modify the $_ string in Perl for at least some of the filenames
  specified.  If a given filename is not modified by the expression, it will not be renamed.  If no filenames are given on the command line, filenames will be read via standard input.

  For example, to rename all files matching "*.bak" to strip the extension, you might say

          rename 's/\.bak$//' *.bak

  To translate uppercase names to lower, you'd use

          rename 'y/A-Z/a-z/' *

Он использует perl, поэтому вы можете использовать выражения perl для соответствия шаблону, на самом деле, я считаю, что он работает так же, как скрипты tchrist.

Другим действительно полезным набором инструментов для переименования большого файла является коллекция renameutils от Oskar Liljeblad. Исходный код размещен Free Software Foundation. Кроме того, многие дистрибутивы (в частности, дистрибутивы на основе Debian/Ubuntu) имеют пакет renameutils с этими инструментами.

На одном из этих дистрибутивов вы можете установить его с помощью:

$ sudo apt-get install renameutils

И затем для переименования файлов просто запустите эту команду:

$ qmv

Он откроет текстовый редактор со списком файлов, и вы сможете манипулировать ими с помощью функции поиска и замены редактора.

Ответ 3

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

1)

for f in *v9.zip; do echo mv "${f}" "${f%v9.zip}.zip"; done

2)

for f in *_*; do echo mv "${f}" "${f//_/-}"; done

Что касается вашей третьей проблемы, я уверен, что это может быть сделано, но, возможно, более сложный подход, чем использование однострочных оболочек из raw shell, как упоминал @tchrist.

Ответ 4

Вышеуказанные ответы относятся к Debian, Ubuntu и т.д.

Для RHEL и co: переименовать from_pattern to_pattern файлы

Ответ 5

Я думаю, что ссылка сломана, и я не смог найти страницу в webarchive для переименования script в tchrist post, так что вот еще один в Perl.

#!/usr/bin/perl
# -w switch is off bc HERE docs cause erroneous messages to be displayed under
# Cygwin
#From the Perl Cookbook, Ch. 9.9
# rename - Larry filename fixer
$help = <<EOF;
Usage: rename expr [files]

This script first argument is Perl code that alters the filename 
(stored in \$_ ) to reflect how you want the file renamed. It can do 
this because it uses an eval to do the hard work. It also skips rename
calls when the filename is untouched. This lets you simply use 
wildcards like rename EXPR * instead of making long lists of filenames.

Here are five examples of calling the rename program from your shell:

% rename 's/\.orig$//'  *.orig
% rename 'tr/A-Z/a-z/ unless /^Make/'  *
% rename '$_ .= ".bad"'  *.f
% rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *
% find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'

The first shell command removes a trailing ".orig" from each filename.

The second converts uppercase to lowercase. Because a translation is
used rather than the lc function, this conversion won't be locale-
aware. To fix that, you'd have to write:

% rename 'use locale; $_ = lc($_) unless /^Make/' *

The third appends ".bad" to each Fortran file ending in ".f", something
a lot of us have wanted to do for a long time.

The fourth prompts the user for the change. Each file name is printed
to standard output and a response is read from standard input. If the
user types something starting with a "y" or "Y", any "foo" in the 
filename is changed to "bar".

The fifth uses find to locate files in /tmp that end with a tilde. It 
renames these so that instead of ending with a tilde, they start with
a dot and a pound sign. In effect, this switches between two common 
conventions for backup files
EOF

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die [email protected] if [email protected];
    rename($was,$_) unless $was eq $_;
}