Suche 2 Dateien mit ähnlichen Namen und verschiebe sie an einen neuen Ort

Suche 2 Dateien mit ähnlichen Namen und verschiebe sie an einen neuen Ort

Ich habe ein System mit einem Überwachungsordner, in den Personen/Unternehmen neue Dateien über FTP oder SMB hochladen können. In diesen Überwachungsordner sollten IMMER 2 Dateien hochgeladen werden: 1 Mediendatei mit einem Präfixnamen ABC*.mxfund immer einer Nummer für „*“. Die andere hat denselben Dateinamen, jedoch mit der .xmlErweiterung.

Beispiel: hochgeladene Dateien sind: ABC0001.mxf, ABC0001.xml

Wenn beispielsweise eine zweite Datei ABC0002.xml hochgeladen wird, die Datei ABC0002.mxf jedoch noch nicht hochgeladen wurde oder nicht vollständig ist, sollte die Datei ABC0002.xml noch NICHT verschoben werden. Nur wenn sowohl ABC*.mxf als auch ABC*.xml übereinstimmende Namen aufweisen und höchstens 5 Minuten alt sind, sollten sie verschoben werden.

Ich muss ein Skript erstellen, das diese beiden identischen Dateien findet (nach Namen, nicht nach Erweiterung) und sie nur verschiebt, wenn die Änderungszeit (mmin) älter als 5 Minuten ist. Es werden also nur abgeschlossene Dateien verschoben.

Außerdem muss ich sagen, dass mehrere Dateien gleichzeitig von verschiedenen Lieferanten hochgeladen werden können. ABC0001.mxf + .xml von Unternehmen 1 und ABC0100.mxf + .xml von Unternehmen 2 und ABC1003.mxf + .xml von Unternehmen 3. Nicht alle werden gleichzeitig fertig.

Ich habe bereits mit einem Teilskript begonnen, habe aber Probleme mit dem Teil mit den passenden Namen.


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

BEARBEITEN: Die Dateinamen wurden von ABC* in ABC*.mxf geändert, da die Mediendatei immer die Erweiterung .mxf hat. Und ein Beispiel zum Hochladen von Dateien hinzugefügt.

Antwort1

Der einfachste Ansatz hängt davon ab, wie sehr Sie Ihren Benutzern vertrauen können. Wenn Sie nicht testen müssen, ob beide Dateien vorhanden sind oder ob die Namen korrekt sind oder sonst etwas, brauchen Sie nicht einmal ein Skript. Sie können dies mit einem einfachen tun find:

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

Wenn Sie sicherstellen müssen, dass i) beide Dateien vorhanden sind und ii) beide mindestens 5 Minuten zuvor geändert wurden, können Sie auf einem GNU-System Folgendes tun:

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

Antwort2

Auf einem GNU-System:

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

Entfernen Sie es echo, wenn die Ausgabe Ihren Wünschen entspricht.

Antwort3

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

(entfernen Sie das „ print -rwenn glücklich“-Symbol).

Oder um mvmehrfache Anrufe zu vermeiden:

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/

verwandte Informationen