Linux trova il file nella cartella e lo sposta in una nuova posizione con il prefisso time


0

Ho una cartella di backup accessibile con sftp. L'idea è che il backup venga in questa cartella ma non dovrebbe rimanere lì. Voglio spostarli con un cron job. Questo è già possibile ma poiché non posso essere sicuro che un nome di file sia univoco, vorrei prefisso il file mentre lo sposto.

* * * * * find /src/backup/ -mmin +60 -exec mv "{}" /dest/backup/ \;

Come posso modificare il comando in modo tale che ether il file stesso abbia un prefisso
per esempio. yyyymmdd-MMSS- o che venga utilizzata una nuova cartella, ad es. yyyymmdd?


2
L'ora è stampata dal tempo di spostamento o dall'ora di modifica del file?
AFH

Preferibile il tempo di modifica del file, ma se ciò non è possibile il tempo di spostamento sarebbe di aiuto.
Webdesigner

Risposte:


1

Avrai bisogno di script per fare questo, quindi non puoi farlo con il -exec opzione direttamente (a meno che non si usi bash -c, che rende difficile la quotazione e l'espansione dei parametri).

Ci sono due opzioni: -

  • Uso find /src/backup/ | while read -r f; do ...; done - Funzionerà se si hanno nomi di file normali (senza spazi iniziali / finali, non newline incorporati).
  • Chiama un file di script che contiene i comandi necessari, ad es find /src/backup/ -mmin +60 -exec /Path/To/moveunique {} /dest/backup/ - in questo caso, consiglio di inserire il percorso completo dello script nel file crontab linea, poiché il suo ambiente è diverso dalla tua shell interattiva.

Illustrerò la prima opzione: dovrebbe essere ovvio come usare comandi simili in un file di script:

find /src/backup/ | while read -r f; do \
    mv "$f" /dest/backup/"${f%/*}"/$(date -d@$(stat "$f" -c %Y) +'%Y%m%d-%H%M')-"${f##*/}"; \
done

Questo usa stat per ottenere il tempo di modifica del file, date per formattare i campi temporali desiderati e l'espansione dei parametri per separare il percorso e il nome della directory del file.

Questo rende una stringa di comando piuttosto lunga (ho usato linee di continuazione per renderlo più leggibile, e non ho controllato se crontab supporta questo), quindi preferisci usare uno script.


La cartella assoluta è ciò che avevi nel tuo originale mv comando, e non è consigliabile utilizzare un percorso relativo in a crontab comando, per la ragione che ho dato sopra. Si potrebbe anche voler omettere la directory sorgente dalla cartella di destinazione, se si desidera che tutti i file di backup in una singola directory.
AFH

Se usi -execdir invece di -exec, un percorso relativo sarà relativo al percorso di ogni file sorgente: è questo che vuoi?
AFH

In alternativa, usa cd /src/backup/; find . {Options} ...; cd "$OLDPWD".
AFH

Sfortunatamente, non ci sono opzioni in mv equivalente a mkdir -p, ma è abbastanza facile incorporare quest'ultimo comando quando si utilizza uno script, che è stato scelto saggiamente come soluzione preferita.
AFH

0

Quindi, poiché ho bisogno di un po 'di flessibilità in qualsiasi modo, mi è venuta in mente una versione di script basata sull'idea di AFH.

#!/bin/sh

# configure: source path
source_path="/src/path/backup";

# configure: destination path
destination_path="/dest/path/backup";

# find all files in source_path not modified in the last 60 minutes
find $source_path -mmin +60 -type f | while read -r file; do

    # this is the absolute source path (/src/path/backup/path/to/file)
    absolute_source_path="${file%/*}";

    # get the relative source path (/path/to/file)
    relative_source_path=${absolute_source_path#$source_path}

    # get the last modification date of the file (yyyymmdd)
    file_save_date="$(date -d@$(stat "$file" -c %Y) +'%Y%m%d')";

    # IMPORTANT create sub directory at the destination if required
    mkdir --parents "$destination_path/$file_save_date$relative_source_path/";

    # move the file to new destination (/dest/path/backup/yyyymmdd/path/to/file)
    mv "$file" "$destination_path/$file_save_date$relative_source_path/" > /dev/null 2>&1;

done

# delete empty folders if the the folder is not changes in the last 5 minutes
find $source_path/* -mmin +5 -type d -empty -delete > /dev/null 2>&1;

1
Non hai bisogno sed per rimuovere il percorso sorgente: puoi ugualmente utilizzare l'espansione dei parametri, che evita il sovraccarico di esecuzione di un programma esterno: relative_source_path=${absolute_source_path#$source_path}.
AFH
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.