
Tengo un almacenamiento similar al siguiente en AzureVM/Ubuntu
-/A
-/B --> 10000 log files
-/C --> 100000 log files
-/D --> 200000 images
summary.xml
-/data --> 1000 csv files
Ahora bien, como el tamaño de los datos es muy grande para calcularlos y realizar cualquier operación allí, quiero tomar una muestra de estos datos para desarrollar mi código de análisis de datos.
Quiero copiar un subconjunto a una ubicación diferente que tenga los 100 archivos más nuevos en cada directorio y directorio anidado y todos los archivos en la raíz, algo como esto.
-/New_Location
-/B --> 100 log files
-/C --> 100 log files
-/D --> 100 images
summary.xml
-/data --> 100 csv files
Probé varios comandos basados en cp pero nada funciona para mí y me lleva demasiado tiempo ejecutarlo.
¿Alguien puede ayudarme aquí?
Respuesta1
Generalmente puedes dividir esto en tres tareas, donde comienzas con la estructura del directorio y luego, como en tu caso, limitas los archivos a 100. La última parte invierte elfósforopara ampliar el alcance del resto de los archivos.
#!/bin/bash
# Example START
[[ ! -d A/ ]] && { \
mkdir -p \
A/{tmp/folder,\
{A..Z}}/{images,data} && \
printf %s\\0 \
A/{summary.xml,\
tmp/De5Loh4X.tmp,\
{A..Z}/{{1..1000}_file.log,\
images/{1..1000}_pic.{jpg,png},\
data/example.csv}} | xargs -0 touch; }
### Example END
set -o noglob
source=A
target=target
number=100
# prune="-false"
prune="-type d -path $source/tmp -prune"
match='-name *.log -o -name *.jpg -o -name *.png'
echo Create directory structure.
find "$source" \
\( $prune -o -type d -links 2 \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
echo Copy 100 files.
while IFS= read -rd ''; do
find "$REPLY" \
-maxdepth 1 -type f \( $match \) -printf '%T@\t%P\0' | sort -zk1rn | cut -zf2- | head -zn $number | cpio -0 -pvdm -D "$REPLY" "$target/${REPLY/#$source\//}"
done < <( \
find "$source" \
\( $prune -false -o -type f \) -printf %h\\0 | sort -zu \
)
echo Copy everything else.
find "$source" \
\( $prune -false -o -type f ! \( $match \) \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
Respuesta2
Esto se puede hacer fácilmente mediante un archivado selectivo. Puede guardar los archivos (solo los deseados) y luego extraer el archivo tar en otro lugar. Supongo que sus archivos de registro tienen el mismo nombre excepto por la numeración (por ejemplo, log1, log2, etc.). Por lo tanto, los primeros cien archivos se pueden definir en el comando tarball como log{1..100}. Por ejemplo:
tar -cvf copied.tar <path1>/log{1..100} <path2>/log({1..100}
etc.
Cuando extraiga, la estructura del archivo original se recreará en la nueva ubicación. Por lo tanto, es posible que necesites usar la opción "--strip-components=" para truncar los directorios principales redundantes y evitar el desorden.