Je crée une vidéo timelapse en scindant une vidéo en images individuelles, en utilisant G'MIC via la ligne de commande pour établir une moyenne toutes les 7 images, puis les résultats sont générés sur de nouvelles images, ce qui donnera les images pour le timelapse. vidéo sans bruit qui a fière allure). Comme vous pouvez l’imaginer, j’ai beaucoup de cadres - plusieurs milliers d’images individuelles dans un répertoire nommé séquentiellement (image1.tiff, image2.tiff, etc.). J'ai trouvé un script qui fonctionne parfaitement pour déplacer les fichiers - une fois ...
k=1; find source/ -type f | while read file; do
[[ k++ -le 7 ]] && mv "$file" target/
done
Ce dont j'ai besoin maintenant, c'est de faire ce script
Juste pour clarifier, le répertoire 1 devrait contenir les images 1-7, le répertoire 2 devrait contenir les images 8-14, etc.
Toute aide est grandement appréciée, je suis plutôt coincé avec celui-ci.
Le script (python) ci-dessous crée des sous-dossiers et organise vos fichiers dans ces dossiers:
Aditionellement:
Le script suppose:
image1.tiff
, image2.tiff
etc (pas de zéros).#!/usr/bin/env python3
import os
import math
import shutil
#---
directory = "/path/to/files" # path to your files
n_perfolder = 7 # number of files per sub folder
#--
# creating file list, extension
f_list = os.listdir(directory); ext = f_list[0].split(".")[-1]
# calculate number of folders
n_folders = math.ceil(len(f_list)/n_perfolder)
# creating folder names, including leading zeros
folders = [str(fn+1) for fn in range(n_folders)]
fl_names = [(len(max(folders, key=len))-len(fl))*"0"+fl for fl in folders]
# creating folders and allocate files
for i in range(len(fl_names)):
mkfolder = directory+"/"+fl_names[i]
if not os.path.exists(mkfolder):
os.makedirs(mkfolder)
r = range(i*n_perfolder+1, i*n_perfolder+n_perfolder+1)
for n in r:
try:
file = directory+"/"+"image"+str(n)+"."+ext
target = mkfolder+"/"+"image"+str(n)+"."+ext
shutil.copyfile(file, target)
except FileNotFoundError:
pass
Copiez le script dans un fichier vide, dans la section head, définissez le répertoire dans vos fichiers et le nombre de fichiers par sous-répertoire, enregistrez-le sous le nom organize.py
.
Exécutez-le à l'aide de la commande:
python3 /path/to/organize.py
Si vous souhaitez déplacer les fichiers au lieu de les copier, remplacez la ligne:
shutil.copyfile(file, target)
par:
shutil.move(file, target)
(attention au retrait!)
Si cela ne vous dérange pas que tout soit déplacé séparément:
#! /bin/bash
for ((i = 1; ; i++))
do
mkdir -p target-$i
for j in $(seq $((i*7 - 6)) $((i*7)))
do
mv -t "target-$i" "source/image$j.tiff" || exit 1
done
done
Ou plus concis:
find source -type f -name 'image*.tiff' -print0 | \
sort -z --version-sort | \
xargs -0n7 bash -c 'TARGET=target-$((${1//[^0-9]/} / 7 + 1)); \
echo mkdir -p "$TARGET"; \
echo mv -t "$TARGET" "$@"' move-7
Explication:
-print0
imprime les noms de fichiers séparés par le caractère NUL (\0
). C'est le moyen le plus sûr de transmettre les noms de fichiers en sortie à d'autres commandes.sort
avec -z
cherche une entrée non délimitée, et le tri de la version nous permet de trier en toute sécurité les nombres de longueur variable, de sorte que image2.tiff
vienne avant image119.tiff
xargs
peut limiter le nombre d'arguments appliqués à chaque commande avec -n
, nous utilisons donc -n7
. Le -0
est pour une entrée non délimitée.$((${1//[^0-9]/} / 7 + 1))
- ${1//[^0-9]/}
supprime tout l'élément de l'argument qui n'est pas un nombre. La division entière assure que nous obtenons le quotient.mv
s requis.Inspectez les commandes générées et, si elles vous conviennent, exécutez-les à nouveau après avoir supprimé les echo
s.
KasiyA a un modification intéressante à cela.
Réponse de JJoao rappelle rename
. Tout d’abord, créez tous les répertoires:
FILES=(source/image*.tiff)
COUNT=${#FILES[@]}
DIR_NUM=$((COUNT / 7 + 1))
seq 1 $DIR_NUM | xargs bash -c 'mkdir -p "${@/#/target-}"'
rename -n 's;source/image(\d+)\.tiff$;"target-".int($1 / 7 - 1)."/image".$1.".tiff";e' source/image*.tiff
En fait, nous pourrions appliquer les quatre premières lignes à toutes les solutions ici et ignorer les répétitions mkdir -p
.
sevenfile=0
newdir=1
for file in `ls -v /path/to/source/image*.tiff` ; do
mkdir -p "$newdir" && mv "$file" "$newdir"
[[ ++sevenfile -eq 7 ]] && sevenfile=0 && ((newdir++))
done
ls -v
trie les fichiers comme une sorte naturelle de numéro (de version).ls
dans ce cas, car tous les fichiers sont spécifiques et ne sont que image*.tiff
.mkdir -p $newdir
crée le répertoire en fonction de la variable newdir
.
mv "$file" "$newdir"
déplace le fichier dans le répertoire spécifié par newdir
.
sevenfile=0
à zéro lorsque 7 fichiers ont été déplacés ([[ ++sevenfile -eq 7 ]]
) et augmentez la valeur newdir
.Notez que changez /path/to/source/
en votre répertoire source actuel.
Si vous ne souhaitez pas analyser la commande ls
et si les noms de fichier incluent des espaces, des nouvelles lignes, etc.:
find /path/to/source/ -type f -name 'image*.tiff' -print0 | \
sort -z --version-sort | while IFS= read -d '' -r file; do \
mkdir -p "$newdir" && mv "$file" "$newdir" ;
[[ ++sevenfile -eq 7 ]] && sevenfile=0 && ((newdir++));
done
#!/usr/bin/Perl
open(F,"-|","ls source/*") or die;
while(<F>){ chomp;
if(/(\d+).tiff/){
$dir= "target-" . (1+int($1/7));
mkdir($dir) unless -d $dir;
system "mv $_ $dir";
}
}