¿Cómo renombrar archivos y reemplazar caracteres?

11

Tengo un grupo de archivos que tienen :(dos puntos) dentro del nombre. Necesito reemplazar el :con -(guión).

¿Hay una manera fácil de hacer esto en un script?

Nombre de archivo de muestra: 2013-10-11:11:52:08_055456663_045585_.txt

Cariño
fuente

Respuestas:

17

Un simple 1-liner debería hacer (asume un shshell compatible con Posix ):

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

Explicación:

  • for ... in ...; do ...; donees un bucle

  • *:* coincide con todos los archivos y directorios en el directorio actual que tienen :en su nombre

  • f se asigna a su vez a cada nombre de archivo en el bucle

  • mvcambia el nombre de su primer argumento al segundo; -v(detallado) le pide que imprima lo que hace; Esta opción es específica de GNU-utils , por lo que está disponible en Linux pero no en Solaris

  • $(...) ejecuta el código en un sub-shell y sustituye la salida

  • echo imprime su argumento a la salida estándar

  • tr lee la salida estándar y traduce los caracteres de acuerdo con el mapa proporcionado

Si está utilizando bash , puede evitar generar un shell adicional ( $()) con subprocesos ( tr) reemplazándolo $(...)con ${f//:/-}.

sds
fuente
+1 para una respuesta de trabajo simple, aunque podría tener un poco más de explicación. Por ejemplo, el for f inciclo ... es un ciclo que itera sobre todos los archivos en el directorio actual donde los archivos deben coincidir *:*. (¿Qué sucede con los directorios que coinciden?). El comando move es move oldname newname donde se genera el nuevo nombre ejecutando un shell con $( subshell here ). Lo que hace, ...
Hennes
@Hennes: esto es superusuario , ¿realmente necesito entrar en este tipo de detalles? Oh bueno, aquí tienes ...
sds
No. Si hubiera una necesidad real, entonces no habría hecho +1. Y entiendo lo que hace. Sin embargo, creo que es bueno para muchos otros lectores.
Hennes
2
Puede reemplazar $(echo "$f" | tr ':' '-')con "${f//:/-}"y evitar la llamada de subprograma, canalización y programa externo. Creo que esto es un bashismo, pero eh. Vea aquí .
evilsoup
@evilsoup De hecho; no hace mucha diferencia para los conjuntos de datos pequeños (y uno podría favorecer la legibilidad), pero se sorprendería de lo rápido que se suma algo así. Me mordió recientemente; reescribir una secuencia de comandos de modo que ya no fueran necesarios dos comandos simples de masaje de cadenas para reducir fácilmente el tiempo de ejecución en un 90% o más, lo que en un gran conjunto de datos se tradujo en varios minutos de tiempo de ejecución de wallclock.
un CVn
6

Como dije en otra publicación, la renameherramienta podría hacer el truco por ti. Solo necesita escribir rename s/:/-/ <files to rename> Esto reemplaza cada punto y coma con un guión en todos los archivos que nombre al final, es decir2013-10-*

Aquí está el enlace a mi otra publicación

noggerl
fuente
1

Estoy seguro de que un profesional de UNIX podría hacer esto con bash, pero aquí está mi versión rápida y sucia con 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

establezca path_to_files en la ruta a sus archivos con nombre incorrecto. guarde el código anterior en un archivo llamado rename.rb y luego:

username@machinename$ ruby rename.rb
shupru
fuente
@sds ofrece una respuesta mucho mejor. ¿Debo eliminar mi respuesta? Soy nuevo en stackoverflow.
shupru
1
No; Todavía tiene un valor significativo. :)
Blacklight Shining
2
Sin embargo, hay algunas desventajas importantes con esta respuesta, que pueden ser relevantes y definitivamente vale la pena conocerlas. (Todavía puede ser útil, pero advierte emptor y todo eso). Principalmente, parece que se romperá mal cuando encuentre nombres de archivos con espacios en blanco (no solo la nueva línea del caso de falla clásico) en ellos. Además, incluso si no fuera por el espacio en blanco, debe citar el nombre del archivo en la invocación del shell para proteger cualquier otro carácter especial en los nombres de archivo del tratamiento por el shell (aunque no sé exactamente cómo funciona el operador de backtick de Ruby )
un CVn
1

Si solo tiene uno o unos pocos archivos, esto puede cambiarle el nombre:

  1. Almacenar el patrón del nombre del archivo que se dirigen como una variable: p="201*".
  2. Almacenar el nombre de archivo antiguo nombre desea cambiar: old_name=$(ls | grep $p).
  3. Almacene el nuevo nombre de archivo con los reemplazos de caracteres necesarios:

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

Bono de limpieza :
  a. Si por razones de uniformidad desea reemplazar los guiones (-) junto con los dos puntos (:) con guiones bajos (_), puede hacer esto:

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

  si. Si desea que el último guión bajo (justo antes del .txt) desaparezca también, configure la new_namevariable como:

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. Ahora cambie el nombre de su archivo según sea necesario: mv $old_name $new_name

         NB: mvfallará si alguno de los nombres de archivo en la operación de cambio de nombre tiene spaces. En ese caso, ajuste las variables apropiadas entre comillas, como:
mv "$old_name" $new_name O mv $old_name "$new_name" O mv "$old_name" "$new_name"


One-liners

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
Deber A.
fuente
0

usando renamer :

$ renamer --find ":" --replace "-" *
Lloyd
fuente
Creo que instalar un entorno completo de node.js para cambiar el nombre de los archivos es demasiado. renamees una herramienta que está preinstalada en muchas distribuciones de Linux. Pero creo que para Windows esta herramienta puede ser genial.
noggerl
0

Esto puede ser excesivo, pero puede cambiar el nombre de cualquier carácter especial con el script en el enlace proporcionado en esta respuesta:

/superuser//a/858671/365691

A.Danischewski
fuente