Sostituisci tutti i due punti dai nomi dei file con il terminale


12

Ho un GB di musica sul mio HDD formattato con EXT4. Voglio spostare questi file in una partizione HDD formattata FAT. Tuttavia, non riesco a spostare la maggior parte dei miei file perché contengono ":" nei nomi (ad esempio "Act 2: ....." per le opere). C'è un modo con la riga di comando per rinominare tutti i miei file da "XXXX: XXXX" a "XXXX-XXXX"?

Risposte:


25

Se tutti i tuoi file si trovano in una singola directory, prova:

rename 's|:|-|g' *

(dove * può essere modificato in qualcosa di più restrittivo se lo desideri)

Se hai molti file in un albero di directory, prova questo dalla base dell'albero:

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

Puoi aggiungere l'opzione -nsubito dopo renameper dirti cosa farebbe SENZA REALMENTE farlo. Questo potrebbe aiutarti a evitare di calpestare accidentalmente altri file o qualcos'altro di brutto ...


1
La soluzione a directory singola funzionerà, ma la soluzione nidificata non funzionerà se le directory stesse hanno: s nei loro nomi. Questo perché nell'output del find .nome di una sottodirectory precede il suo contenuto. Quindi, se si dispone /1:/2:prima di un file, /1:/verrà rinominato /1-/. Ora non è possibile rinominare /1:/2:a /1-/2-causa /1:/2:non esiste.
S Prasanth,

1
Per le directory: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;E poi i file:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;

@Christopher Il comando per le directory fallirà se ci sono due livelli di directory con: nei loro nomi. Ad esempio: / 1: / 2: / dove 2: è anche una directory. Naturalmente, se questo non è il caso della situazione di Ryan, allora funzionerà.
S Prasanth,

Per più livelli di sub-directory utilizzare: for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Cambia 20 alla massima profondità della dir. struttura. Non deve essere esatto, può essere più grande. Ci vorrà del tempo se impostato su un numero molto grande però.
S Prasanth,

0

Non sono sulla mia macchina Linux in questo momento, quindi posso solo dare informazioni di massima.

Linux ha un'utilità a riga di comando chiamata renameche funziona con altri input, espressioni regolari o regex. Dovresti essere in grado di usarlo insieme a una regex come "s /: / - /" sui tuoi file per ottenere la rinomina che desideri.

Solo per sicurezza, fallo in piccoli lotti e / o prima prova con la simulazione (rinominare ha un flag che ti dà solo il vecchio nome e il nuovo nome del file senza effettivamente rinominarlo - usa questo per verificare prima)


0

Questa è una soluzione in Python che gestisce il caso in cui i file non si trovano necessariamente nella stessa directory.

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. Salvalo in un file (ad esempio) rename.py.
  2. Passare rootdiralla directory più esterna in esame (utilizzare il nome percorso completo che inizia con /. Nessuna scorciatoia o variabili env come ~ consentite). Non c'è bisogno di mettere \ davanti a caratteri speciali - ad esempio se la directory più esterna è /.../Mio HDD, inserisci rootdir = "/.../My HDD"NOT rootdir = "/.../My\ HDD"(nota la "s) [Sono esplicito solo perché potresti non avere familiarità con Python. Non mancare di rispetto previsto.]
  3. Passare logfilealla posizione desiderata del file di registro. Alla fine, questo file conterrà l'elenco dei file rinominati, per riferimento futuro.
  4. Chiama python rename.py.

Avvertenza: eseguire un test su un piccolo campione prima di rischiare un intero GB di musica.

Dettagli: la ridenominazione viene eseguita dai file più interni verso l'esterno.


0

Mi rendo conto che questo è un post molto vecchio. La soluzione ricorsiva di AeroGT80 è molto accurata, ma è piuttosto lenta. L'ho fatto funzionare per circa mezz'ora su un server più lento e solo circa la metà - penso che fossero circa 73.000 file in circa 300 sottodirectory.

La soluzione seguente funzionerà molto più rapidamente (funziona su tutti i file in una directory, anziché su ogni file uno per uno - usando la soluzione non ricorsiva di AeroGT80). L'unico problema è che scende in profondità solo una directory (quindi non è completamente ricorsivo come la sua soluzione), ma sono sicuro che potrebbe essere modificato abbastanza facilmente.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.