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

3

Eu tenho um sistema com uma pasta monitorada onde as pessoas / empresas podem fazer upload de novos arquivos via FTP ou SMB. Nesta pasta de monitoração Eles devem sempre carregar 2 arquivos: 1 arquivo de mídia com um prefixo de ABC*.mxf e sempre um número para '*'. O outro é o mesmo nome de arquivo, mas com a extensão .xml .

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 estiver carregado ou não estiver completo, o arquivo ABC0002.xml NÃO deverá ainda ser movido. somente quando ABC * .mxf e ABC * .xml têm nomes correspondentes e são 5 min ou mais, eles devem ser movidos.

Eu preciso criar um script que encontre esses dois arquivos idênticos (por nome e não extensão) e mova-os somente se o tempo de modificação (mmin) for maior que 5 minutos. Então, apenas arquivos completos são movidos.

Também devo dizer que vários arquivos podem ser enviados 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 terminando nos mesmos horários.

Eu já comecei com um script parcial, mas estou lutando com a parte de 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.

    
por SHLelieveld 14.05.2014 / 09:19

3 respostas

2

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 do tipo, 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ê precisa 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ê poderia fazer isto:

 
#!/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
    
por 14.05.2014 / 13:33
1

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 o echo se a saída for o que você deseja.

    
por 14.05.2014 / 11:05
1

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 -r se estiver feliz).

Ou para evitar chamar mv vá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/
    
por 14.05.2014 / 13:21