Déplacer des fichiers MP4 dans le bon dossier selon l’heure

Gregoryen

Membre actif
Club iGen
16 Juin 2013
677
45
33
Arles
www.gregoryen.fr
Salut tout le monde,

J’ai besoin d’aide sur un script .sh que j’ai créé avec l’aide de ChatGPT pour déplacer des fichiers MP4 d’un dossier source à un dossier destination, en fonction de la date et de l’heure des fichiers. Le script fonctionne bien pour l’instant, mais je souhaite ajouter une règle supplémentaire, et c’est là que je galère vraiment.

Contexte :

• Mes fichiers MP4 ont une date et une heure dans leur nom. « 25-10-2024 15-05-29.mp4 »
• Mes dossiers de destination sont nommés avec une date spécifique. « [14] Ven-25-10-2024 » (14 étant le numéro du dossier)
• Mon script actuel déplace les fichiers dans le dossier correspondant à leur date, puis renomme les fichiers en retirant l’heure et en ajoutant un numéro entre crochets, qui s’incrémente au fur et à mesure (ex. [1], [2], etc.). Si un fichier est déjà dans le dossier avec [1], le prochain sera renommé en [2], etc.
• Le script s’exécute toutes les minutes et marche très bien pour ça.

La complexité supplémentaire :

Je veux que tous les fichiers créés entre minuit et cinq heures du matin soient considérés comme appartenant à la veille. Par exemple, si on est le 2 janvier entre minuit et cinq heures, je voudrais que ces fichiers soient déplacés dans le dossier du 1er janvier. De même, l’incrémentation des numéros entre crochets doit continuer de manière cohérente avec les fichiers déjà présents dans ce dossier.

Ce que j’ai tenté :

ChatGPT m’a aidé pour une bonne partie, mais pour cette logique de bascule de date entre minuit et cinq heures, ça coince. J’ai passé des nuits dessus, mais rien n’y fait : ça bugge ou ça ne fonctionne pas comme je veux.

Si quelqu’un a une idée pour intégrer cette logique dans le script, ça me sauverait. Je vous poste le code que j’ai pour le moment, en espérant que quelqu’un puisse m’aiguiller sur cette partie.

Merci d’avance !

Bash:
#!/bin/bash


# Chemins des dossiers où sont enregistrées les vidéos
source_folders=(
"/Users/gregoryen/Scripts/TEST/SOURCE"
)


# Dossier de base à partir duquel tu veux rechercher les sous-dossiers
base_folder="/Users/gregoryen/Scripts/TEST/DESTINATION"

# Taille minimale autorisée en Mo
min_size_mb=10

# Fonction pour générer le nouveau nom du fichier
generate_new_filename() {
    local date_part="$1"
    local destination_folder="$2"
    local counter=1
    local new_filename=""

    while true; do
        new_filename="${date_part}-[${counter}].mp4"
        if [ ! -e "${destination_folder}/${new_filename}" ]; then
            break
        fi
        ((counter++))
    done

    echo "$new_filename"
}

# Fonction pour vérifier si le fichier est en cours de création
is_file_still_writing() {
    local file="$1"
    local initial_size=$(du -m "$file" | cut -f1)
    sleep 5  # Attendre 5 secondes
    local new_size=$(du -m "$file" | cut -f1)

    # Vérifie si la taille a changé
    if [ "$initial_size" -ne "$new_size" ]; then
        return 0  # Le fichier est encore en cours d'écriture
    else
        return 1  # Le fichier est prêt à être déplacé
    fi
}

# Parcours des dossiers sources
for source_folder in "${source_folders[@]}"; do
    # Vérifier si des fichiers MP4 existent dans le dossier source
    if [ -n "$(ls -A "$source_folder"/*.mp4 2>/dev/null)" ]; then
        # Parcours des fichiers MP4 dans le dossier source
        for video_file in "$source_folder"/*.mp4; do
            # Vérifier la taille du fichier
            file_size=$(du -m "$video_file" | cut -f1)

            # Vérifier si le nom du fichier contient "Replay"
            if [[ "$video_file" == *"Replay"* ]]; then
                echo "Le fichier $video_file contient 'Replay' et sera ignoré."
                continue
            fi
           
            if [ "$file_size" -ge "$min_size_mb" ]; then
                # Extraire la date du nom du fichier
                file_name=$(basename "$video_file")
                date_part=$(echo "$file_name" | grep -oE '[0-9]{2}-[0-9]{2}-[0-9]{4}' | head -n1)

                if [ -n "$date_part" ]; then
                    # Recherche du dossier correspondant dans la structure à partir du dossier de base
                    destination_subfolder=$(find "$base_folder" -type d -name "*$date_part*" | head -n 1)

                    if [ -n "$destination_subfolder" ]; then
                        # Chemin du sous-dossier « Découpage par tranche de 2 heures »
                        final_destination="${destination_subfolder}/Découpage par tranche de 2 heures"

                        # Créer le sous-dossier s'il n'existe pas
                        if [ ! -d "$final_destination" ]; then
                            mkdir -p "$final_destination"
                            echo "Sous-dossier créé : $final_destination"
                        fi

                        # Attendre 30 secondes avant de vérifier le fichier
                        echo "Attente de 30 secondes avant de vérifier $video_file."
                        sleep 30

                        # Vérifier si le fichier est encore en cours d'écriture
                        if is_file_still_writing "$video_file"; then
                            echo "Le fichier $video_file est encore en cours de création, il ne sera pas déplacé."
                            continue
                        fi

                        # Vérifier à nouveau la taille du fichier avant de le déplacer
                        file_size=$(du -m "$video_file" | cut -f1)

                        if [ "$file_size" -ge "$min_size_mb" ]; then
                            # Générer le nouveau nom du fichier
                            new_filename=$(generate_new_filename "$date_part" "$final_destination")

                            # Déplacer le fichier MP4 avec le nouveau nom dans le sous-dossier
                            mv "$video_file" "${final_destination}/${new_filename}"
                            echo "Le fichier $file_name a été déplacé vers ${final_destination}/${new_filename}."
                        else
                            echo "Le fichier $video_file est inférieur à ${min_size_mb} Mo après vérification et ne sera pas déplacé."
                        fi
                    else
                        echo "Aucun dossier correspondant à la date $date_part n'a été trouvé dans la structure de dossiers."
                    fi
                else
                    echo "La date n'a pas pu être extraite du fichier $file_name."
                fi
            else
                echo "Le fichier $video_file est inférieur à ${min_size_mb} Mo et ne sera pas déplacé."
            fi
        done
    else
        echo "Aucun fichier MP4 trouvé dans le dossier $source_folder."
    fi
done
 
Bon j'ai mis le mode Python sur ChatGPT, et il me l'a trouvé du premier coup, contrairement à ChatGPT classique, et ça fonctionne du feu de dieu !
Bloc de code:
#!/bin/bash

# Chemins des dossiers où sont enregistrées les vidéos
source_folders=(
"/Users/gregoryen/Scripts/TEST/SOURCE"
)

# Dossier de base à partir duquel tu veux rechercher les sous-dossiers
base_folder="/Users/gregoryen/Scripts/TEST/DESTINATION"

# Taille minimale autorisée en Mo
min_size_mb=10

# Fonction pour générer le nouveau nom du fichier
generate_new_filename() {
    local date_part="$1"
    local destination_folder="$2"
    local counter=1
    local new_filename=""

    while true; do
        new_filename="${date_part}-[${counter}].mp4"
        if [ ! -e "${destination_folder}/${new_filename}" ]; then
            break
        fi
        ((counter++))
    done

    echo "$new_filename"
}

# Fonction pour vérifier si le fichier est en cours de création
is_file_still_writing() {
    local file="$1"
    local initial_size=$(du -m "$file" | cut -f1)
    sleep 5  # Attendre 5 secondes
    local new_size=$(du -m "$file" | cut -f1)

    # Vérifie si la taille a changé
    if [ "$initial_size" -ne "$new_size" ]; then
        return 0  # Le fichier est encore en cours d'écriture
    else
        return 1  # Le fichier est prêt à être déplacé
    fi
}

# Fonction pour ajuster la date si l'heure est entre 00:00 et 05:00
adjust_date_if_needed() {
    local date_part="$1"
    local time_part="$2"
    local adjusted_date="$date_part"

    # Vérifier si l'heure est entre minuit et 5 heures du matin
    if [[ "$time_part" < "05:00:00" ]]; then
        # Ajuster la date à la veille
        adjusted_date=$(date -j -f "%d-%m-%Y" -v-1d "$date_part" "+%d-%m-%Y")
    fi

    echo "$adjusted_date"
}

# Parcours des dossiers sources
for source_folder in "${source_folders[@]}"; do
    # Vérifier si des fichiers MP4 existent dans le dossier source
    if [ -n "$(ls -A "$source_folder"/*.mp4 2>/dev/null)" ]; then
        # Parcours des fichiers MP4 dans le dossier source
        for video_file in "$source_folder"/*.mp4; do
            # Vérifier la taille du fichier
            file_size=$(du -m "$video_file" | cut -f1)

            # Vérifier si le nom du fichier contient "Replay"
            if [[ "$video_file" == *"Replay"* ]]; then
                echo "Le fichier $video_file contient 'Replay' et sera ignoré."
                continue
            fi
          
            if [ "$file_size" -ge "$min_size_mb" ]; then
                # Extraire la date et l'heure du nom du fichier
                file_name=$(basename "$video_file")
                date_part=$(echo "$file_name" | grep -oE '[0-9]{2}-[0-9]{2}-[0-9]{4}' | head -n1)
                time_part=$(echo "$file_name" | grep -oE '[0-9]{2}-[0-9]{2}-[0-9]{2}' | tail -n1 | tr '-' ':')

                if [ -n "$date_part" ] && [ -n "$time_part" ]; then
                    # Ajuster la date si l'heure est entre minuit et 5 heures
                    adjusted_date_part=$(adjust_date_if_needed "$date_part" "$time_part")

                    # Recherche du dossier correspondant dans la structure à partir du dossier de base
                    destination_subfolder=$(find "$base_folder" -type d -name "*$adjusted_date_part*" | head -n 1)

                    if [ -n "$destination_subfolder" ]; then
                        # Chemin du sous-dossier « Découpage par tranche de 2 heures »
                        final_destination="${destination_subfolder}/Découpage par tranche de 2 heures"

                        # Créer le sous-dossier s'il n'existe pas
                        if [ ! -d "$final_destination" ]; then
                            mkdir -p "$final_destination"
                            echo "Sous-dossier créé : $final_destination"
                        fi

                        # Attendre 30 secondes avant de vérifier le fichier
                        echo "Attente de 30 secondes avant de vérifier $video_file."
                        sleep 30

                        # Vérifier si le fichier est encore en cours d'écriture
                        if is_file_still_writing "$video_file"; then
                            echo "Le fichier $video_file est encore en cours de création, il ne sera pas déplacé."
                            continue
                        fi

                        # Vérifier à nouveau la taille du fichier avant de le déplacer
                        file_size=$(du -m "$video_file" | cut -f1)

                        if [ "$file_size" -ge "$min_size_mb" ]; then
                            # Générer le nouveau nom du fichier
                            new_filename=$(generate_new_filename "$adjusted_date_part" "$final_destination")

                            # Déplacer le fichier MP4 avec le nouveau nom dans le sous-dossier
                            mv "$video_file" "${final_destination}/${new_filename}"
                            echo "Le fichier $file_name a été déplacé vers ${final_destination}/${new_filename}."
                        else
                            echo "Le fichier $video_file est inférieur à ${min_size_mb} Mo après vérification et ne sera pas déplacé."
                        fi
                    else
                        echo "Aucun dossier correspondant à la date $adjusted_date_part n'a été trouvé dans la structure de dossiers."
                    fi
                else
                    echo "La date ou l'heure n'a pas pu être extraite du fichier $file_name."
                fi
            else
                echo "Le fichier $video_file est inférieur à ${min_size_mb} Mo et ne sera pas déplacé."
            fi
        done
    else
        echo "Aucun fichier MP4 trouvé dans le dossier $source_folder."
    fi
done