copie una gran cantidad de archivos en un orden de directorio estructurado por fecha

copie una gran cantidad de archivos en un orden de directorio estructurado por fecha

Necesito copiar alrededor de 40,0000 archivos en carpetas estructuradas por fechas.
archivo de ejemplo:

/var/public/voicelogging/quality_monitoring/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

Es uno de los muchos archivos que necesito copiar/home/username/logging/

El nombre del archivo tiene 2 variables que necesito usar:

bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

20151209Por supuesto, la fecha
12434es la identificación del usuario que creó el archivo.

Lo que necesito es un script/una línea que pueda buscar en un directorio la identificación del usuario.

Luego cree un directorio con la identificación del usuario en formato /home/username/logging. Después de crear la carpeta, necesita crear un directorio para cada fecha que pueda encontrar.
Y coloque cada archivo en el userid/datedirectorio correcto.
ejemplo de directorio de resultados.

/home/username/logging/12434/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

He creado un resumen para crear el directorio de fecha, pero aún necesito crear el directorio de identificación de usuario yo mismo.

find /var/public/voicelogging/quality_monitoring/ -type f -name "*12434*" | sed -r 's/^.{65}//' | cut -c1-8 | xargs -I {} mkdir {} /home/username/logging/12434

¿Cómo puedo copiar el archivo correcto en el lugar correcto?

Respuesta1

Unidireccional con findy install:

find /var/public/voicelogging/quality_monitoring -name \*.WAV -exec sh -c '
bn=${0##*/}; x=${bn%%-*}; dt=${x##*_}; y=${bn%_*}; id=${y##*_} 
install -D "$0" "/home/username/logging/${id}/${dt}/${bn}"' {} \;

esto usa la expansión de parámetros para extraer la fecha: ${dt}y la identificación del usuario: ${id}del nombre del archivo y luego usainstallcopiar cada archivo al userID/datedirectorio correspondiente (esto es porque soy vago) - sin installreemplazar la última línea con:

dest=/home/username/logging/${id}/${dt}; mkdir -p "${dest}" && cp "$0" "${dest}"' {} \;

Si prefiere recorrer esos directorios de "fecha" y luego recorrer los .WAVarchivos en cada directorio:

for d in /var/public/voicelogging/quality_monitoring/*; do
  dt=${d##*/}
  for f in $d/*.WAV; do
    bn=${f##*/}; y=${bn%_*}; id=${y##*_}
    dest=/home/username/logging/${id}/${dt}
    mkdir -p "${dest}" && cp "${f}" "${dest}"
  done
done

Si lo tiene, zshes más fácil y más corto zmv(también porque zshes más inteligente y puede anidar expansiones variables, por ejemplo, ${${file%_*}##*_}sería suficiente para extraer la identificación del usuario):

dtcp () {                                                                     
mkdir -p $3 && cp $1 $2 $3
}
autoload zmv
zmv -n -p dtcp '/var/public/voicelogging/quality_monitoring/(*)/(*).WAV' \
'/home/username/logging/${${2%_*}##*_}/$1'

Los (*)s crean referencias posteriores que se pueden usar en el segundo parámetro como $1, $2etc.
Aquí zmvwith -pejecuta la función dtcpen lugar de mv. La función crea el directorio y luego copia el archivo al directorio recién creado. Los argumentos (que no deben confundirse con las referencias anteriores anteriores) son:
$1: --
que significa fin de opciones
$2: /var/public/voicelogging/quality_monitoring/(*)/(*).WAV'
ese es el archivo que debe copiarse y
$3: /home/username/logging/${${2%_*}##*_}/$1
cuál es el destino
Nota que -nsignificaejecución en seco; elimínelo para ejecutar el comando.

información relacionada