Заменить все двоеточия из имен файлов с терминалом

12

У меня на жестком диске музыка в ГБ, отформатированная в EXT4. Я хочу переместить эти файлы в раздел жесткого диска в формате FAT. Тем не менее, я не могу переместить большинство моих файлов, потому что они имеют «:» в именах (например, «Act 2: .....» для опер). Есть ли способ с помощью командной строки переименовать все мои файлы из «XXXX: XXXX» в «XXXX-XXXX»?

Райан МакКлюр
источник

Ответы:

25

Если все ваши файлы находятся в одном каталоге, попробуйте:

rename 's|:|-|g' *

(где * можно изменить на что-то более ограничительное, если хотите)

Если у вас есть много файлов в дереве каталогов, попробуйте это из базы дерева:

find . -name "*:*" -exec rename 's|:|-|g' {} \;

Вы можете добавить опцию -nсразу после того rename, как он скажет вам, что он будет делать без ФАКТИЧЕСКИ. Это может помочь вам избежать случайного наступления на другие файлы или что-то еще плохое ...

AeroGT80
источник
1
Решение с одним каталогом будет работать, но вложенное решение не будет работать, если у самих каталогов есть свои имена. Это потому, что в выводе find .имя подкаталога предшествует его содержимому. Так что если у вас есть файл, /1:/2:сначала /1:/он будет переименован в /1-/. Теперь вы не можете переименовать /1:/2:в /1-/2-потому , что /1:/2:не существует.
S Prasanth
1
Для каталогов: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;А потом файлы:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;
@Christopher Команда для каталогов потерпит неудачу, если есть два уровня каталогов с: в их именах. Например: / 1: / 2: / где 2: также каталог. Конечно, если это не так в ситуации Райана, то это будет работать.
S Prasanth
Для нескольких уровней суб-директорий использовать: for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Измените 20 на максимальную глубину реж. состав. Не должен быть точным - может быть больше. Это займет время, если установлено очень большое число, хотя.
S Prasanth
0

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

В Linux есть утилита командной строки, renameкоторая работает с другими входными данными, регулярными выражениями или регулярными выражениями. Вы должны иметь возможность использовать это вместе с регулярным выражением типа "s /: / - /" в ваших файлах для достижения желаемого переименования.

Просто чтобы быть в безопасности, делайте это небольшими партиями и / или первым тестом с симуляцией (переименование имеет флаг, который просто дает вам старое имя и новое имя файла без фактического переименования - сначала используйте это для проверки)

Картик Т
источник
0

Это решение в Python, которое обрабатывает случай, когда файлы не обязательно находятся в одном каталоге.

import os
torename = []
rootdir = "The main directory"
logfile = "Path to log file" #Eg: logfile = "/home/prasanth/renamelog"
for (path, dirs, files) in os.walk(rootdir):
    for dirname in dirs:
        if ':' in dirname:
            torename.append(os.path.join(path, dirname))
    for filename in files:
        if ':' in filename:
            torename.append(os.path.join(path, filename))

print "No of files/dirs to rename =", len(torename)
a = raw_input("Continue? (y/n) ")
if a == 'y':
    torename.reverse()
    for oldname in torename:
        directory, filename = os.path.split(oldname)
        newname = os.path.join(directory, filename.replace(':', '-'))
        command = 'mv %s %s > /dev/null' % (repr(oldname), repr(newname))
        os.system(command)
        f = open(logfile, 'a')
        f.write(oldname + '\n')
        f.close()
else:
    print "Aborted."
  1. Сохраните это в файл (скажем) rename.py.
  2. Перейдите rootdirк самому рассматриваемому каталогу (используйте полный путь, начинающийся с /. Никаких сокращений или переменных env, таких как ~ разрешено). Не нужно ставить \ перед специальными символами - например, если самый внешний каталог - /.../Мой жесткий диск, поставьте rootdir = "/.../My HDD"НЕ rootdir = "/.../My\ HDD"(обратите внимание на «s») [Я говорю это явно только потому, что вы можете быть незнакомы с python. Нет неуважения предназначена.]
  3. Перейдите logfileв нужное место файла журнала. В конце концов, этот файл будет содержать список файлов, переименованных - для дальнейшего использования.
  4. Вызов python rename.py.

Предупреждение: сделайте тест на небольшом образце, прежде чем рисковать целым ГБ музыки.

Детали: переименование выполняется из самых внутренних файлов наружу.

S Prasanth
источник
0

Я понимаю, что это очень старый пост. Рекурсивное решение AeroGT80 очень тщательное, но довольно медленное. Я работал около получаса на более медленном сервере, и это было сделано только наполовину - я думаю, что это было около 73 000 файлов в около 300 подкаталогах.

Приведенное ниже решение будет работать намного быстрее (оно работает со всеми файлами в каталоге, а не с каждым файлом по одному - используя нерекурсивное решение AeroGT80). Единственная проблема в том, что он уходит только в один каталог (поэтому он не является полностью рекурсивным, как его решение), но я уверен, что его можно изменить достаточно легко.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Адам Плохер
источник