varios renombrar recursivamente masivo masivamente lista comando buscar archivos file unix rename batch-rename

file - recursivamente - renombrar lista de archivos linux



Renombra múltiples archivos en Unix (20)

Hay varios archivos en un directorio que comienzan con el prefijo fgh , por ejemplo:

fghfilea fghfileb fghfilec

Quiero cambiar el nombre de todos para comenzar con el prefijo jkl . ¿Hay un solo comando para hacer eso en lugar de renombrar cada archivo individualmente?


Aquí hay una forma de hacerlo usando la línea de comandos Groovy:

groovy -e ''new File(".").eachFileMatch(~/fgh.*/) {it.renameTo(it.name.replaceFirst("fgh", "jkl"))}''


Así es como sed y mv se pueden usar juntos para cambiar el nombre:

for f in fgh*; do mv "$f" $(echo "$f" | sed ''s/^fgh/jkl/g''); done

Según el comentario a continuación, si los nombres de los archivos tienen espacios, es posible que las comillas deban rodear la subfunción que devuelve el nombre para mover los archivos a:

for f in fgh*; do mv "$f" "$(echo $f | sed ''s/^fgh/jkl/g'')"; done


El cambio de nombre podría no estar en todos los sistemas. así que si no lo tiene, use el shell este ejemplo en bash shell

for f in fgh*; do mv "$f" "${f/fgh/xxx}";done


En Solaris puedes probar:

for file in `find ./ -name "*TextForRename*"`; do mv -f "$file" "${file/TextForRename/NewText}" done


Escribí este script para buscar todos los archivos .mkv que cambian de nombre recursivamente los archivos encontrados a .avi. Puedes personalizarlo según tus necesidades. He agregado algunas otras cosas, como obtener el directorio de archivos, la extensión, el nombre de archivo de una ruta de archivo en caso de que necesite consultar algo en el futuro.

find . -type f -name "*.mkv" | while read fp; do fd=$(dirname "${fp}"); fn=$(basename "${fp}"); ext="${fn##*.}"; f="${fn%.*}"; new_fp="${fd}/${f}.avi" mv -v "$fp" "$new_fp" done;


Esto me funcionó usando regexp:

Quería que los archivos fueran renombrados así:

file0001.txt -> 1.txt ofile0002.txt -> 2.txt f_i_l_e0003.txt -> 3.txt

usig [az | _] + 0 * ([0-9] +. ) regexp donde ([0-9] +. ) es una subcadena de grupo para usar en el comando rename

ls -1 | awk ''match($0, /[a-z|/_]+0*([0-9]+.*)/, arr) { print arr[0] " " arr[1] }''|xargs -l mv

Produce:

mv file0001.txt 1.txt mv ofile0002.txt 2.txt mv f_i_l_e0003.txt 3.txt

Otro ejemplo:

file001abc.txt -> abc1.txt ofile0002abcd.txt -> abcd2.txt ls -1 | awk ''match($0, /[a-z|/_]+0*([0-9]+.*)([a-z]+)/, arr) { print arr[0] " " arr[2] arr[1] }''|xargs -l mv

Produce:

mv file001abc.txt abc1.txt mv ofile0002abcd.txt abcd2.txt

Advertencia, ten cuidado.


Fue mucho más fácil (en mi Mac) hacer esto en Ruby. Aquí hay 2 ejemplos:

# for your fgh example. renames all files from "fgh..." to "jkl..." files = Dir[''fgh*''] files.each do |f| f2 = f.gsub(''fgh'', ''jkl'') system("mv #{f} #{f2}") end # renames all files in directory from "021roman.rb" to "021_roman.rb" files = Dir[''*rb''].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/} files.each do |f| f1 = f.clone f2 = f.insert(3, ''_'') system("mv #{f1} #{f2}") end


Hay muchas maneras de hacerlo (no todas estas funcionarán en todos los sistemas unixy):

  • ls | cut -c4- | xargs -I§ mv fgh§ jkl§

    El § puede ser reemplazado por cualquier cosa que le parezca conveniente. Puedes hacer esto con find -exec también, pero eso se comporta de manera muy diferente en muchos sistemas, por lo que generalmente evito eso.

  • for f in fgh*; do mv "$f" "${f/fgh/jkl}";done

    Crudo pero efectivo como dicen

  • rename ''s/^fgh/jkl/'' fgh*

    Muy bonito, pero el cambio de nombre no está presente en BSD, que es el sistema de UNIX más común.

  • rename fgh jkl fgh*

  • ls | perl -ne ''chomp; next unless -e; $o = $_; s/fgh/jkl/; next if -e; rename $o, $_'';

    Si insistes en usar Perl, pero no hay cambio de nombre en tu sistema, puedes usar este monstruo.

Algunos de ellos son un poco complicados y la lista está lejos de ser completa, pero aquí encontrará lo que desea para prácticamente todos los sistemas UNIX.


Hay varias formas, pero usar rename probablemente sea la más fácil.

Usando una versión de rename :

rename ''s/^fgh/jkl/'' fgh*

Usando otra versión de rename (igual que la respuesta de Judy2K ):

rename fgh jkl fgh*

Debes consultar la página de manual de tu plataforma para ver cuál de las anteriores aplica.


Mi versión de renombrar archivos masivos:

for i in *; do echo "mv $i $i" done | sed -e "s#from_pattern#to_pattern#g” > result1.sh sh result1.sh


Para instalar el script de rename Perl:

sudo cpan install File::Rename

Hay dos renombramientos como se menciona en los comentarios en la respuesta de Stephan202. Las distribuciones basadas en Debian tienen el rename . Las distros redhat / rpm tienen el rename
OS X no tiene uno instalado de forma predeterminada (al menos en 10.8), ni Windows / Cygwin.


Recomendaría usar mi propio script, que resuelve este problema. También tiene opciones para cambiar la codificación de los nombres de los archivos y convertir los signos diacríticos en caracteres precompuestos, un problema que siempre tengo cuando copio archivos desde mi Mac.

https://github.com/kugland/rename.pl/blob/master/rename.pl


También puede utilizar el siguiente script. Es muy fácil de ejecutar en la terminal ...

// Renombrar múltiples archivos a la vez

for file in FILE_NAME* do mv -i "${file}" "${file/FILE_NAME/RENAMED_FILE_NAME}" done

Ejemplo:-

for file in hello* do mv -i "${file}" "${file/hello/JAISHREE}" done


Un script genérico para ejecutar una expresión sed en una lista de archivos (combina la solución sed con la solución para rename el rename ):

#!/bin/sh e=$1 shift for f in $*; do fNew=$(echo "$f" | sed "$e") mv "$f" "$fNew"; done

Invoca pasando la secuencia de comandos una expresión sed y luego cualquier lista de archivos, como una versión de rename :

script.sh ''s/^fgh/jkl/'' fgh*


Usando StringSolver herramientas de StringSolver (Windows y Linux bash) que se procesan con ejemplos:

filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea

Primero calcula un filtro basado en ejemplos , donde la entrada son los nombres de archivo y la salida (ok y notok, cadenas arbitrarias). Si el filtro tenía la opción --auto o se invocó solo después de este comando, crearía una carpeta ok y una carpeta notok y notok archivos respectivamente a ellos.

Luego, utilizando el filtro, el comando mv es un movimiento semiautomático que se vuelve automático con el modificador --auto. Usando el filtro anterior gracias a --filter, encuentra una asignación de fghfilea a jklfilea y luego la aplica a todos los archivos filtrados.

Otras soluciones de una línea

Otras formas equivalentes de hacer lo mismo (cada línea es equivalente), para que pueda elegir su forma favorita de hacerlo.

filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea" # Even better, automatically infers the file name filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"

Solución de varios pasos

Para encontrar con cuidado si los comandos funcionan bien, puede escribir lo siguiente:

filter fghfilea ok filter fghfileb ok filter fghfileb notok

y cuando esté seguro de que el filtro es bueno, realice el primer movimiento:

mv fghfilea jklfilea

Si desea realizar una prueba y usar el filtro anterior, escriba:

mv --test --filter

Si la transformación no es lo que deseaba (p. Ej., Incluso con mv --explain que ve que algo está mal), puede escribir mv --clear para reiniciar archivos en movimiento, o agregar más ejemplos mv input1 input2 donde input1 y input2 son otros ejemplos.

Cuando tengas confianza, solo escribe

mv --filter

¡y voilá! Todo el cambio de nombre se realiza mediante el filtro.

DESCARGO DE RESPONSABILIDAD: Soy coautor de este trabajo realizado con fines académicos. También podría haber una característica de producción de bash pronto.


Usando find , xargs y sed :

find . -name "fgh*" -type f -print0 | xargs -0 -I {} sh -c ''mv "{}" "$(dirname "{}")/`echo $(basename "{}") | sed ''s/^fgh/jkl/g''`"''

Es más complejo que la solución de @nik, pero permite renombrar archivos de forma recursiva. Por ejemplo, la estructura,

. ├── fghdir │   ├── fdhfilea │   └── fghfilea ├── fghfile/ e ├── fghfilea ├── fghfileb ├── fghfilec └── other ├── fghfile/ e ├── fghfilea ├── fghfileb └── fghfilec

se transformaría en esto,

. ├── fghdir │   ├── fdhfilea │   └── jklfilea ├── jklfile/ e ├── jklfilea ├── jklfileb ├── jklfilec └── other ├── jklfile/ e ├── jklfilea ├── jklfileb └── jklfilec

La clave para hacer que funcione con xargs es invocar el shell desde xargs .


Utilizando mmv :

mmv "fgh*" "jkl#1"


Utilizando renamer :

$ renamer --find /^fgh/ --replace jkl * --dry-run

Elimine el --dry-run una vez que esté satisfecho, la salida se ve correcta.


#!/bin/sh #replace all files ended witn .f77 to .f90 in a directory for filename in *.f77 do #echo $filename #b= echo $filename | cut -d. -f1 #echo $b mv "${filename}" "${filename%.f77}.f90" done


rename fgh jkl fgh*