encontre 2 arquivos com nomes semelhantes e mova-os para um novo local

encontre 2 arquivos com nomes semelhantes e mova-os para um novo local

Tenho um sistema com uma pasta monitorada onde pessoas/empresas podem fazer upload de novos arquivos via FTP ou SMB. Nesta pasta monitorada, eles devem SEMPRE fazer upload de 2 arquivos: 1 arquivo de mídia com um nome de prefixo ABC*.mxfe sempre um número para '*'. O outro tem o mesmo nome de arquivo, mas com a .xmlextensão.

exemplo: os arquivos enviados são: ABC0001.mxf, ABC0001.xml

se um segundo arquivo ABC0002.xml for carregado, mas o ABC0002.mxf ainda não tiver sido carregado ou não estiver concluído, o arquivo ABC0002.xml NÃO deverá ser movido ainda. somente quando ABC*.mxf e ABC*.xml tiverem nomes correspondentes e tiverem 5 minutos ou mais, eles deverão ser movidos.

Preciso criar um script que encontre esses 2 arquivos idênticos (por nome, não por extensão) e só os mova se o tempo de modificação (mmin) for superior a 5 minutos. Portanto, apenas os arquivos concluídos são movidos.

Também devo dizer que vários arquivos podem ser carregados ao mesmo tempo por diferentes fornecedores. ABC0001.mxf + .xml pela empresa 1, e ABC0100.mxf + .xml pela empresa 2, e ABC1003.mxf + .xml pela empresa 3. Nem todos finalizando no mesmo horário.

Já comecei com um script parcial, mas estou tendo dificuldades com a parte dos nomes correspondentes.


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

EDIT: alterou os nomes dos arquivos de ABC* para ABC*.mxf porque o arquivo de mídia sempre tem a extensão .mxf. E adicionou um exemplo de upload de arquivo.

Responder1

A abordagem mais simples dependerá de quanto você pode confiar em seus usuários. Se você não precisa testar se os dois arquivos existem ou se os nomes estão corretos ou algo assim, você nem precisa de um script. Você pode fazer isso com um simples find:

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

Se você precisar ter certeza de que i) ambos os arquivos estão lá e ii) ambos têm um tempo de modificação de pelo menos 5 minutos atrás, em um sistema GNU, você pode fazer o seguinte:

#!/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

Responder2

Em um 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

Remova echose a saída for a que você deseja.

Responder3

Com 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/
}

(remova o print -rse estiver feliz).

Ou para evitar ligar mvvárias vezes:

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/

informação relacionada