2012-09-25 14 views
6

Estoy intentando copiar todos los archivos de un directorio a otro, eliminando todas las extensiones de archivo al mismo tiempo.Cómo uso find para copiar y eliminar extensiones manteniendo la misma estructura de subdirectorio

From directory 0001: 
0001/a/1.jpg 
0001/b/2.txt 

To directory 0002: 
0002/a/1 
0002/b/2 

He intentado varios encontrar ... | xargs c ... p sin suerte.

+0

¿Cuál debería ser el comportamiento si hay dos archivos (por ejemplo, 1.txt y 1.jpg) en el mismo directorio que tienen el mismo nombre además de la extensión? –

+0

todos los nombres de archivo vienen precedidos de una identificación única, por lo que no existe el riesgo de nombrar colisiones. – user1345178

Respuesta

4

Las copias recursivas son muy fáciles de usar con tar. En su caso:

tar -C 0001 -cf - --transform 's/\(.\+\)\.[^.]\+$/\1/' . | 
tar -C 0002 -xf - 
+0

+1 - debe cambiar la expresión regular: eliminando universalmente cualquier extensión, no solo jpg (OP pregunte eso) - pero de lo contrario, buena solución. – kobame

+1

esta nueva expresión regular está casi bien, pero ¿qué hará esta, por ejemplo, con el nombre de archivo ".profile"? – kobame

+0

Buena solución. Probado con 260000 archivos (4 horas). – user1345178

0

me ocurrió con este patito feo:

find 0001 -type d | sed 's/^0001/0002/g' | xargs mkdir 
find 0001 -type f | sed 's/^0001//g' | awk -F '.' '{printf "cp -p 0001%s 0002%s\n", $0, $1}' | sh 

La primera línea crea el árbol de directorios, y las segundas copias de línea de los archivos. Los problemas con este son:

  1. No solamente es el manejo de los directorios y archivos normales (no enlaces simbólicos etc.)
  2. Si hay algunos períodos (además de la extensión ) o caracteres especiales (espacios, etc.) en los nombres de archivo , entonces el segundo comando no funcionará.
2

Si no lo ha tar con --transform Esto puede obras:

TRG=/target/some/where 
SRC=/my/source/dir 
cd "$SRC" 
find . -type f -name \*.\* -printf "mkdir -p '$TRG/%h' && cp '%p' '$TRG/%p'\n" |\ 
    sed 's:/\.::;s:/./:/:' |\ 
    xargs -I% sh -c "%" 

No hay espacios después de la \, necesitan extremo de la línea sencilla, o puede unirse a una línea como:

find . -type f -name \*.\* -printf "mkdir -p '$TRG/%h' && cp '%p' '$TRG/%p'\n" | sed 's:/\.::;s:/./:/:' | xargs -I% sh -c "%" 

Explicación:

  • del find encontrará todos archivos planos lo que tiene extensiones en ti SRC (fuente) guía
  • de printf preparará los comandos shell necesarios del hallazgo: comando
    • para crear el árbol de directorios necesaria en el TRG (dir objetivo)
    • comando para copiar
  • sed el camino haciendo limpieza cosmética, (como /some/path/./other/dir corregir)
  • la xargs se toman toda la línea
  • y ejecutar los comandos preparados con la cáscara

embargo, será mucho mejor:

  • simplemente crea un exacta copia de primera etapa
  • renombrar archivos en el 2 ° paso

más fácil, más limpio y más RÁPIDO (no necesita c hecking/creando los subdires de destino)!

+0

Estoy interesado en el enfoque de 2 pasos ya que el directorio contiene alrededor de 1000000 archivos. así que MÁS RÁPIDO es el rey. – user1345178

+0

archivos Milion? entonces, en este caso (IMO), el alquitrán dos es la mejor solución. Si no ha tar con --transform, descárguelo y compile. Seguramente será más rápido que iniciar comandos milion cp. – jm666

1

Aquí hay algunos encuentran + fiesta + instalación que va a hacer el truco:

for src in `find 0001 -type f` # for all files in 0001... 
do 
    dst=${src/#0001/0002}   # match and change beginning of string 
    dst=${dst%.*}     # strip extension 
    install -D $src $dst   # copy to dst, creating directories as necessary 
done 

Esto cambiará el modo de permiso de todos los archivos copiados en rwxr-xr-x por defecto, modificable con la opción de instalar --mode.

+0

+1 para esto, estaba a punto de escribir esa respuesta. Más elegante aquí y la herramienta adecuada :) – Zlatko

Cuestiones relacionadas