busque 2 archivos con nombres similares y muévalos a una nueva ubicación

busque 2 archivos con nombres similares y muévalos a una nueva ubicación

Tengo un sistema con una carpeta de vigilancia donde las personas/empresas pueden cargar nuevos archivos a través de FTP o SMB. En esta carpeta de vigilancia SIEMPRE deben cargar 2 archivos: 1 archivo multimedia con un nombre de prefijo ABC*.mxfy siempre un número para '*'. El otro es el mismo nombre de archivo, pero con la .xmlextensión.

ejemplo: los archivos cargados son: ABC0001.mxf, ABC0001.xml

Si se carga un segundo archivo ABC0002.xml pero el ABC0002.mxf aún no está cargado o no está completo, el archivo ABC0002.xml NO debe moverse aún. solo cuando ABC*.mxf y ABC*.xml tienen nombres coincidentes y tienen 5 minutos o más, se deben mover.

Necesito crear un script que encuentre estos 2 archivos idénticos (por nombre, no por extensión) y solo los mueva si el tiempo de modificación (mmin) es superior a 5 minutos. Por lo tanto, sólo se mueven los archivos completos.

También debo decir que diferentes proveedores pueden cargar varios archivos al mismo tiempo. ABC0001.mxf + .xml por la empresa 1, y ABC0100.mxf + .xml por la empresa 2, y ABC1003.mxf + .xml por la empresa 3. No todos terminan al mismo tiempo.

Ya comencé con un guión parcial, pero tengo problemas con la parte de nombres coincidentes.


SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"

for FOUND in `find $SOURCEDIR/AutoIngest -maxdepth 1 \
    -type f -name ^ABC* -mmin +5 `;     
do     
    mv "$FOUND" "$DESTDIR/"    
done

EDITAR: cambió los nombres de los archivos de ABC* a ABC*.mxf porque el archivo multimedia siempre tiene la extensión .mxf. Y agregó un ejemplo de carga de archivos.

Respuesta1

El enfoque más sencillo dependerá de cuánto puedas confiar en tus usuarios. Si no necesita probar que ambos archivos existen o que los nombres son correctos ni nada, ni siquiera necesita un script. Puedes hacer esto con un simple find:

find /dir/to/source -name "ABC*" -mmin +5 -exec mv {} /destination/dir \;

Si necesita asegurarse de que i) ambos archivos estén allí y ii) ambos tengan una hora de modificación de hace al menos 5 minutos, en un sistema GNU, puede hacer esto:

#!/usr/bin/env bash

SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"

for f in "${SOURCEDIR}"/*.xml; do
    ## Make sure the file exists and is a regular file (or symlink to regular file),
    ## and that its modification date is at least 5 minutes ago
    [ -f "$f" ] && [ "$(( $(date +%s) - $(stat -c %Y "$f") ))" -ge 300 ] || continue

    ## Do the same for a file of the same name but with the .mxf extension.
    mxf="${SOURCEDIR}/$(basename "$f" .xml).mxf";
    [ -f "$mxf" ] && [ "$(( $(date +%s) - $(stat -c %Y "$no_ext") ))" -ge 300 ] || continue

    ## We will only get to this point if all of the above tests were successful
    echo mv -v "$f" "$mxf" "$DESTDIR"
done

Respuesta2

En un sistema GNU:

SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"
TIMESTAMP_MINDIFF=300

timestamp="$(date +%s)"
find "$SOURCEDIR/AutoIngest" -maxdepth 1 -type f -name 'ABC*' ! -name '*.xml' |
  while IFS= read -r file; do
    xmlfile="${file}.xml"
    test -f "$xmlfile" || continue
    ts_file="$(date --reference="$file" +%s)"
    ts_xmlfile="$(date --reference="$xmlfile" +%s)"
    if [ "$((timestamp-ts_file))" -gt "$TIMESTAMP_MINDIFF" ] &&
       [ "$((timestamp-ts_xmlfile))" -gt "$TIMESTAMP_MINDIFF" ]; then
      echo mv "$file" "$xmlfile" "$DESTDIR/"
    fi
  done

Elimine echosi la salida es la que desea.

Respuesta3

Con zsh:

cd /dir/to/source || exit
files=(ABC*(N.mm+5))
for f ($files[(k)*.xml]) {
   (($files[(I)$f:r])) && print -r mv -v -- $f $f:r /destination/dir/
}

(elimine el print -rsi está contento).

O para evitar llamar mvvarias veces:

cd /dir/to/source || exit
files=(ABC*(N.mm+5))
tomove=()
for f ($files[(k)*.xml]) {
   (($files[(I)$f:r])) && tomove+=($f $f:r)
}
print -r mv -- $tomove /destination/dir/

información relacionada