¿Cómo puede mover (o copiar) todos los archivos de cierto tipo a un directorio en Unix?

22

Todavía no estoy muy familiarizado con todos los trucos grep/find/awk/xargs.

Tengo algunos archivos que coinciden con un patrón particular, por ejemplo *.xxx. Estos archivos están en lugares aleatorios en un determinado directorio. ¿Cómo puedo encontrar todos esos archivos y moverlos a una carpeta en mi directorio de inicio en Unix (que puede que aún no exista)?

qodeninja
fuente
44
Debes tener cuidado al hablar sobre el "tipo de archivo". En entornos unixy, el ejemplo ".xxx" ni siquiera es una extensión en el sentido de Windows. ".xxx" solo constituye un sufijo del nombre del archivo. "Tipo de archivo" es más una de las pocas categorías: archivo normal, archivo de dispositivo, enlace simbólico, directorio, canalización con nombre, socket de familia Unix, tal vez algunos otros.
Bruce Ediger
1
Ver también: unix.stackexchange.com/questions/7027/…
jasonwryan
@BruceEdiger gracias, supongo que realmente quise decir "patrón de nombre de archivo"
qodeninja 03 de

Respuestas:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
fuente
1
Yo usaríamv -i -t ~/dst {} +
enzotib
17

Si desea mover todos los archivos dentro de una jerarquía de directorios a un solo directorio de destino, en bash ≥4 (poner shopt -s globstaren su ~/.bashrc) o zsh:

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

En otras conchas:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

Cómo leer este findcomando:

  • .: atraviesa el directorio actual
  • -name '*.xxx': actuar en archivos cuyo nombre coincide con este patrón
  • -exec … \;: ejecuta este comando en cada archivo, reemplazándolo {}por la ruta al archivo

Hay un comando más complejo findque es más rápido si tiene muchos archivos, ya que no necesita invocar un mvproceso separado para cada archivo:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

Al +final le dice findque invoque el comando en varios archivos a la vez. Como findsolo puede poner los nombres de archivo al final de la línea de comando y mvnecesita tener el directorio de destino al final, usamos un shell intermedio para reorganizar los argumentos ( "$0"es el primer argumento para el shell ~/new-directory, y "$@"son los argumentos subsiguientes que provienen de findexpansión de {}).

Gilles 'SO- deja de ser malvado'
fuente
4

Si desea replicar la estructura de directorios de los archivos de origen coincidentes en el nuevo directorio de destino, puede utilizar la opción --parents de GNU cp :

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
frielp
fuente
3

se puede utilizar sin hallazgo -exec‍así:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Ken Zein
fuente
1
Sin embargo, find -exectenga en cuenta que es mucho más seguro; lo anterior fallará en los nombres de archivos que contienen espacios en blanco, por ejemplo.
dhag