Substituir todos os dois pontos dos nomes de arquivos pelo terminal


12

Eu tenho um valor de GB de música no meu HDD que foi formatado com EXT4. Quero mover esses arquivos para uma partição de disco rígido formatada em FAT. No entanto, não consigo mover a maioria dos meus arquivos porque eles têm ":" nos nomes (por exemplo, "Ato 2: ....." para óperas). Existe uma maneira com a linha de comando renomear todos os meus arquivos de "XXXX: XXXX" para "XXXX-XXXX"?

Respostas:


25

Se todos os seus arquivos estiverem em um único diretório, tente:

rename 's|:|-|g' *

(onde * pode ser alterado para algo mais restritivo, se você desejar)

Se você possui muitos arquivos em uma árvore de diretórios, tente isso na base da árvore:

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

Você pode adicionar a opção -nlogo depois renamepara que ela lhe diga o que faria sem REALMENTE fazê-lo. Isso pode ajudá-lo a evitar pisar acidentalmente em outros arquivos ou em algo mais ruim ...


1
A solução de diretório único funcionará, mas a solução aninhada não funcionará se os próprios diretórios tiverem: s em seus nomes. Isso ocorre porque na saída do find .nome de um subdiretório precede seu conteúdo. Portanto, se você tiver um arquivo /1:/2:primeiro /1:/, será renomeado para /1-/. Agora você não pode renomear /1:/2:para /1-/2-porque /1:/2:não existe.
S Prasanth

1
Para diretórios: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;E então arquivos:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;

@Christopher O comando para diretórios falhará se houver dois níveis de diretórios com: em seus nomes. Por exemplo: / 1: / 2: / em que 2: também é um diretório. Obviamente, se esse não for o caso na situação de Ryan, isso funcionará.
S Prasanth

Para vários níveis de sub-dirs usar: for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Altere 20 para a profundidade máxima do dir. estrutura. Não precisa ser exato - pode ser maior. Porém, levará tempo se for definido para um número muito grande.
precisa

0

Eu não estou na minha máquina Linux agora, então só posso fornecer informações aproximadas.

O Linux possui um utilitário de linha de comando chamado renameque funciona com outras entradas, expressões regulares ou expressões regulares. Você poderá usá-lo junto com uma regex como "s /: / - /" em seus arquivos para obter a renomeação desejada.

Para garantir a segurança, faça-o em pequenos lotes e / ou primeiro teste com a simulação (renomear possui um sinalizador que fornece apenas o nome antigo e o novo nome do arquivo sem realmente renomear - use-o para verificar primeiro)


0

Esta é uma solução em python que lida com o caso em que os arquivos não estão necessariamente no mesmo diretório.

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. Salve isso em um arquivo (digamos) rename.py.
  2. Mude rootdirpara o diretório mais externo em consideração (use o nome completo do caminho começando com /. Nenhuma abreviação ou variáveis ​​env como ~ permitida). Não é necessário colocar \ antes de caracteres especiais - por exemplo, se o diretório mais externo for /.../My HDD, coloque rootdir = "/.../My HDD"NOT rootdir = "/.../My\ HDD"(Observe os "s) [Estou sendo explícito apenas porque você pode não estar familiarizado com o python. Sem desrespeito pretendido.]
  3. Mude logfilepara o local desejado do arquivo de log. No final, esse arquivo conterá a lista de arquivos renomeados - para referência futura.
  4. Ligue python rename.py.

Aviso: teste em uma pequena amostra antes de arriscar um GB inteiro de música.

Detalhes: A renomeação é realizada a partir dos arquivos mais internos.


0

Sei que este é um post muito antigo. A solução recursiva do AeroGT80 é muito completa, mas é bem lenta. Eu o executei por cerca de meia hora em um servidor mais lento e só foi concluído pela metade - acho que eram cerca de 73.000 arquivos em cerca de 300 subdiretórios.

A solução abaixo funcionará muito mais rapidamente (opera em todos os arquivos em um diretório, em vez de cada arquivo, um por um - usando a solução não recursiva do AeroGT80). O único problema é que ele apenas desce profundamente em um diretório (por isso não é totalmente recursivo como a solução dele), mas tenho certeza de que poderia ser modificado com bastante facilidade.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.