Question
J'ai 16 000 jpg d'un webcan screeb grabber que j'ai laissé courir pendant un an pour l'année précédente. Je veux trouver un moyen de saisir chaque 4ème image afin de pouvoir ensuite les placer dans un autre répertoire afin de pouvoir les transformer ultérieurement en film. Existe-t-il un script bash simple ou un autre moyen sous Linux que je puisse le faire?
Ils sont nommés comme suit ......
frame-44558.jpg
frame-44559.jpg
frame-44560.jpg
frame-44561.jpg
Merci d'un newb ayant besoin d'aide.
Semble avoir travaillé. Un couple d'erreurs dans mon post d'origine. Il y avait en fait 280 000 images et le nom était. /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163405.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163505.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163605.jpg
j'ai couru. cp $ (ls | awk '{nr ++; if (nr% 10 == 0) print $ 0}') ../ newdirectory /
Qui semble avoir copié les images. 70-900 par jour à partir des apparences.
Maintenant je cours mencoder mf: //*.jpg -mf w = 640: h = 480: fps = 30: type = jpg -ovc lavc -lavcopts vcodec = msmpeg4v2 -nosound -o ../ output-msmpeg4v2.avi
Je vous ferai savoir comment fonctionne le film.
UPDATE: le film n'a pas fonctionné. Ne contient que des images de 2007, même si le répertoire contient également 2008. webcam_2008-02-17_101403.jpg webcam_2008-03-27_192205.jpg webcam_2008-02-17_102403.jpg webcam_2008-03-27_193205.jpg webcam_2008-02-17_103403.jpg webcam_2008-03-27_194205.jpg webcam_2008-02-17_104403.jpg webcam_2008-03-27_195205.jpg
Comment modifier ma ligne mencoder afin qu'elle utilise toutes les images?
La solution
Une méthode simple consiste à:
$ touch a b c d e f g h i j k l m n o p q r s t u v w x y z $ mv $(ls | awk '{nr++; if (nr % 4 == 0) print <*>}') destdir
Autres conseils
Créez un script move.sh qui contient ceci:
#!/bin/sh
mv $4 ../newdirectory/
Rendez-le exécutable puis faites-le dans le dossier:
ls *.jpg | xargs -n 4 ./move.sh
Ceci prend la liste des noms de fichiers, passe quatre à la fois dans move.sh, qui ignore ensuite les trois premiers et déplace le quatrième dans un nouveau dossier.
Cela fonctionnera même si les nombres ne sont pas exactement dans l'ordre (par exemple, si certains numéros de trame manquent, utiliser l'arithmétique mod 4 ne fonctionnera pas).
Comme suggéré, vous devriez utiliser
seq -f 'frame-%g.jpg' 1 4 number-of-frames
pour générer la liste des noms de fichiers car "ls" échouera sur 280 000 fichiers. Donc, la solution finale serait quelque chose comme:
for f in `seq -f 'frame-%g.jpg' 1 4 number-of-frames` ; do
mv $f destdir/
done
seq -f 'frame-%g.jpg' 1 4 number-of-frames
… imprimera les noms des fichiers dont vous avez besoin.
Un moyen simple de perl (probablement facilement adaptable à bash) consiste à déplacer les noms de fichiers dans un tableau, puis à obtenir le numéro de séquence et à supprimer ceux qui ne sont pas divisibles par 4
Quelque chose comme cela imprimera les fichiers dont vous avez besoin:
ls -1 /path/to/files/ | perl -e 'while (<STDIN>) {($seq)=/(\d*)\.jpg$/; print Un moyen simple de perl (probablement facilement adaptable à bash) consiste à déplacer les noms de fichiers dans un tableau, puis à obtenir le numéro de séquence et à supprimer ceux qui ne sont pas divisibles par 4
Quelque chose comme cela imprimera les fichiers dont vous avez besoin:
<*>
Vous pouvez remplacer l'impression par un mouvement ...
Ceci fonctionnera si les fichiers sont numérotés en séquence, même si le nombre de chiffres n'est pas constant, comme fichier_9.jpg
suivi de fichier_10.jpg
)
. if $seq && $seq % 4 ==0}'
Vous pouvez remplacer l'impression par un mouvement ...
Ceci fonctionnera si les fichiers sont numérotés en séquence, même si le nombre de chiffres n'est pas constant, comme fichier_9.jpg
suivi de fichier_10.jpg
)
Compte tenu des mises en garde de masto concernant le tri:
ls | sed -n '1 ~ 4 p' | xargs -i mv {} ../ destdir /
Ce que j’aime dans cette solution, c’est que tout se passe comme prévu, donc ça me fait l’unixy.
Il suffit de parcourir une liste de fichiers:
files=( frame-*.jpg )
i=0
while [[ $i -lt ${#files} ]] ; do
cur_file=${files[$i]}
mungle_frame $cur_file
i=$( expr $i + 4 )
done
C’est plutôt ringard, mais il devrait faire son travail. En supposant que vous soyez actuellement dans le répertoire contenant tous vos fichiers:
mkdir ../outdir
ls | sort -n | while read fname; do mv "$fname" ../outdir/; read; read; read; done
Le sort -n
existe en supposant que vos noms de fichiers n'ont pas tous le même nombre de chiffres; sinon ls
va trier dans l'ordre lexical où frame-123.jpg
précède frame-4.jpg
et je ne pense pas que c'est ce que vous veux.
Faites attention, sauvegardez vos fichiers avant d'essayer ma solution, etc. Je ne veux pas être tenu responsable de votre perte de données pour un an.
Notez que cette solution gère les fichiers avec des espaces dans le nom, contrairement à la plupart des autres. Je sais que cela ne faisait pas partie des exemples de noms de fichiers, mais il est facile d'écrire des commandes shell qui ne gèrent pas les espaces en toute sécurité, c'est pourquoi je voulais le faire dans cet exemple.