Как переименовать файлы и заменить символы?

11

У меня есть группа файлов, которые имеют :(двоеточие) в имени. Мне нужно заменить :с -(тире).

Есть ли простой способ сделать это в сценарии?

Образец FileName: 2013-10-11:11:52:08_055456663_045585_.txt

душка
источник

Ответы:

17

Простой 1-лайнер должен делать (предполагается, что Posix sh-совместимая оболочка):

for f in *:*; do mv -v "$f" $(echo "$f" | tr ':' '-'); done

Объяснение:

  • for ... in ...; do ...; doneэто петля

  • *:* сопоставляет все файлы и каталоги в текущем каталоге, которые имеют :в своем имени

  • f присваивается по очереди каждому такому имени файла в цикле

  • mvпереименовывает свой первый аргумент во второй; -v(многословно) просит его напечатать, что он делает; эта опция специфична для GNU-утилит , поэтому она доступна в Linux, но не в Solaris

  • $(...) выполняет код в под-оболочке и заменяет вывод

  • echo выводит свой аргумент в стандартный вывод

  • tr читает стандартный вывод и переводит символы в соответствии с прилагаемой картой

Если вы используете bash , вы можете избежать появления дополнительной оболочки ( $()) с подпроцессами ( tr) путем замены $(...)на ${f//:/-}.

ДСН
источник
+1 за простой рабочий ответ, хотя это могло бы сделать с немного большим количеством объяснения. Например, for f inцикл ... - это цикл, который перебирает все файлы в текущем каталоге, где файлы должны совпадать *:*. (Что происходит с папками, которые совпадают?). Команда перемещения - это перемещение старого имени на новое имя, в котором новое имя создается путем выполнения оболочки с помощью $( subshell here ). Что тр, делает ...
Хеннес
@Hennes: это суперпользователь - мне действительно нужно вдаваться в детали такого рода? Ну что ж, вот и все ...
SDS
Нет. Если бы была реальная необходимость, я бы не добавил +1. И я понимаю, что он делает. Я думаю, что это хорошо для многих других читателей.
Хенн
2
Вы можете заменить $(echo "$f" | tr ':' '-')с "${f//:/-}"и избежать подоболочку, трубы и внешнего вызова программы. Я думаю, что это башизм, но да. Смотрите здесь .
evilsoup
@evilsoup Действительно; это не имеет большого значения для небольших наборов данных (и можно предпочесть удобочитаемость), но вы будете удивлены, насколько быстро что-то подобное складывается. Я получил немного в последнее время; переписать сценарий так, чтобы две простые команды массирования строк больше не были необходимы, легко сокращая время выполнения на 90% или более, что при большом наборе данных переводилось в несколько минут времени выполнения Wallclock.
CVn
6

Как указано в другом моем сообщении, renameинструмент может помочь вам. Вам просто нужно набрать rename s/:/-/ <files to rename> Это заменяет каждое двоеточие тире во всех файлах, которые вы называете в конце, т.е.2013-10-*

Вот ссылка на мой другой пост

noggerl
источник
1

Я уверен, что UNIX pro мог бы сделать это с bash, но вот моя быстрая и грязная версия с ruby.

path_to_files = "/home/username/wrongnames/"
filenames = `ls #{path_to_files}`.split
filenames.each do |fn|
  `mv #{path_to_files + fn} #{path_to_files + fn.gsub(/:/, "-")}`
end

установите path_to_files на путь к вашим файлам с ошибочными именами. сохраните приведенный выше код в файле с именем rename.rb, а затем:

username@machinename$ ruby rename.rb
shupru
источник
@sds дает гораздо лучший ответ. Должен ли я удалить свой ответ? Я новичок в stackoverflow.
Шупру
1
Нет; это все еще имеет значительную ценность. :)
Blacklight Shining
2
Однако у этого ответа есть несколько существенных недостатков, которые могут иметь отношение к делу и о которых определенно стоит знать. (Это может все еще быть полезным, но будьте осторожны, emptor и все такое.) В первую очередь, похоже, что он плохо сломается, когда встретит имена файлов с пробелами (не только с классическим переводом в новую строку). Кроме того, даже если бы это было не для пробела, вы должны указать имя файла в вызове оболочки, чтобы защитить любые другие специальные символы в именах файлов от обработки оболочкой (хотя я не знаю точно, как работает оператор Ruby backtick ).
CVn
1

Если у вас есть только один или несколько файлов, это может сделать переименование для вас:

  1. Храните образец имени файла , который вы ориентируетесь в качестве переменной: p="201*".
  2. Храните старое имя файла , который вы хотите переименовать: old_name=$(ls | grep $p).
  3. Сохраните новое имя файла с необходимыми заменами символов:

    new_name=$(ls | grep $p | sed 's/:/_/g')        # Using 'sed'
    
                OR
    
    new_name=$(ls | grep $p | tr ':' '_')           # Using 'tr'
    

Бонус очистки :
  а. Если для единообразия вы хотите заменить дефисы (-) вместе с двоеточиями (:) на подчеркивание (_), вы можете сделать это:

    new_name=$(ls | grep $p | tr ':-' '_');

  б. Если вы хотите, чтобы последний знак подчеркивания (непосредственно перед .txt) также исчез, установите new_nameпеременную как:

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. Теперь переименуйте ваш файл по мере необходимости: mv $old_name $new_name

         NB: mvпроизойдет сбой, если в нем есть какое-либо из имен файлов в операции переименования spaces. В этом случае оберните соответствующие переменные в кавычки, например:
mv "$old_name" $new_name ИЛИ mv $old_name "$new_name" ИЛИ mv "$old_name" "$new_name"


Однострочники

1a: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | sed 's/:/_/g'); mv $old_name $new_name

1b: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':' '_'); mv $old_name $new_name

2: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_'); mv $old_name $new_name

3: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./'); mv $old_name $new_name
Дут А.
источник
0

используя renamer :

$ renamer --find ":" --replace "-" *
Lloyd
источник
Я думаю, что установка полной среды node.js только для переименования файлов - это слишком много. renameэто инструмент, который предустановлен во многих дистрибутивах Linux. Но я думаю, что для Windows этот инструмент может быть отличным.
noggerl
0

Это может быть излишним, но вы можете переименовать любые специальные символы с помощью скрипта по ссылке, приведенной в этом ответе:

/superuser//a/858671/365691

A.Danischewski
источник