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
20151209
Por supuesto, la fecha
12434
es 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/date
directorio 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 find
y 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 usainstall
copiar cada archivo al userID/date
directorio correspondiente (esto es porque soy vago) - sin install
reemplazar 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 .WAV
archivos 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, zsh
es más fácil y más corto zmv
(también porque zsh
es 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
, $2
etc.
Aquí zmv
with -p
ejecuta la función dtcp
en 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 -n
significaejecución en seco; elimínelo para ejecutar el comando.