Reemplazar todos los dos puntos de los nombres de archivo con terminal

12

Tengo un valor de GB de música en mi HDD que fue formateada con EXT4. Quiero mover estos archivos a una partición HDD con formato FAT. Sin embargo, no puedo mover la mayoría de mis archivos porque tienen ":" en los nombres (por ejemplo, "Acto 2: ....." para las óperas). ¿Hay alguna manera con la línea de comando para cambiar el nombre de todos mis archivos de "XXXX: XXXX" a "XXXX-XXXX"?

Ryan McClure
fuente

Respuestas:

25

Si todos sus archivos están en un solo directorio, intente:

rename 's|:|-|g' *

(donde * se puede cambiar a algo más restrictivo si lo desea)

Si tiene muchos archivos en un árbol de directorios, intente esto desde la base del árbol:

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

Puede agregar la opción -ninmediatamente después renamepara que le diga qué haría SIN REALMENTE hacerlo. Esto podría ayudarlo a evitar pisar accidentalmente otros archivos o algo malo ...

AeroGT80
fuente
1
La solución de directorio único funcionará, pero la solución anidada no funcionará si los directorios tienen: s en sus nombres. Esto se debe a que en la salida del find .nombre de un subdirectorio precede a su contenido. Entonces, si tiene un archivo /1:/2:primero, /1:/se le cambiará el nombre /1-/. Ahora no puede cambiar el nombre /1:/2:a /1-/2-porque /1:/2:no existe.
S Prasanth
1
Para directorios: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;Y luego archivos:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;
@Christopher El comando para directorios fallará si hay dos niveles de directorios con: en sus nombres. Por ejemplo: / 1: / 2: / where 2: también es un directorio. Por supuesto, si este no es el caso en la situación de Ryan, entonces esto funcionará.
S Prasanth
Para múltiples niveles de sub-dirs usar: for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Cambie 20 a la profundidad máxima del directorio. estructura. No tiene que ser exacto, puede ser más grande. Sin embargo, llevará tiempo si se configura en un número muy grande.
S Prasanth
0

No estoy en mi máquina Linux en este momento, así que solo puedo dar información aproximada.

Linux tiene una utilidad de línea de comandos llamada renameque funciona con otras entradas, expresiones regulares o expresiones regulares. Debería poder usar eso junto con una expresión regular como "s /: / - /" en sus archivos para lograr el cambio de nombre que desea.

Solo para estar seguro, hágalo en pequeños lotes y / o en la primera prueba con la simulación (el cambio de nombre tiene una bandera que solo le da el nombre antiguo y el nombre nuevo del archivo sin cambiar el nombre; use esto para verificar primero)

Karthik T
fuente
0

Esta es una solución en python que maneja el caso donde los archivos no están necesariamente en el mismo directorio.

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. Guarde esto en un archivo (digamos) rename.py.
  2. Cambie rootdiral directorio más externo en consideración (use el nombre de ruta completo que comience con /. No se permiten shorthands o variables de entorno como ~) No es necesario poner \ antes de caracteres especiales; por ejemplo, si el directorio más externo es /.../Mi HDD, ponga rootdir = "/.../My HDD"NOT rootdir = "/.../My\ HDD"( tenga en cuenta las "s" [Estoy siendo explícito solo porque puede no estar familiarizado con Python. No faltar al respeto destinado a.]
  3. Cambie logfilea la ubicación deseada del archivo de registro. Al final, este archivo contendrá la lista de archivos renombrados, para referencia futura.
  4. Llamar python rename.py.

Advertencia: haga una prueba en una muestra pequeña antes de arriesgar un GB completo de música.

Detalles: el cambio de nombre se realiza desde los archivos más internos hacia afuera.

S Prasanth
fuente
0

Me doy cuenta de que esta es una publicación muy antigua. La solución recursiva de AeroGT80 es muy completa, pero es bastante lenta. Lo tuve funcionando durante aproximadamente media hora en un servidor más lento y solo completé la mitad, creo que fueron aproximadamente 73,000 archivos en aproximadamente 300 subdirectorios.

La solución a continuación funcionará mucho más rápido (funciona en todos los archivos en un directorio, en lugar de cada archivo uno por uno, utilizando la solución no recursiva de AeroGT80). El único problema es que solo baja un directorio de profundidad (por lo que no es totalmente recursivo como lo es su solución), pero estoy seguro de que podría modificarse con la suficiente facilidad.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Adam Plocher
fuente