Question

I have 16,000 jpg's from a webcan screeb grabber that I let run for a year pointing into the back year. I want to find a way to grab every 4th image so that I can then put them into another directory so I can later turn them into a movie. Is there a simple bash script or other way under linux that I can do this.

They are named like so......

frame-44558.jpg

frame-44559.jpg

frame-44560.jpg

frame-44561.jpg

Thanks from a newb needing help.


Seems to have worked. Couple of errors in my origonal post. There were actually 280,000 images and the naming was. /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

I ran. cp $(ls | awk '{nr++; if (nr % 10 == 0) print $0}') ../newdirectory/

Which appears to have copied the images. 70-900 per day from the looks of it.

Now I'm running mencoder mf://*.jpg -mf w=640:h=480:fps=30:type=jpg -ovc lavc -lavcopts vcodec=msmpeg4v2 -nosound -o ../output-msmpeg4v2.avi

I'll let you know how the movie works out.

UPDATE: Movie did not work. Only has images from 2007 in it even though the directory has 2008 as well. 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

How can I modify my mencoder line so that it uses all the images?

Was it helpful?

Solution

One simple way is:

$ 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 $0}') destdir

OTHER TIPS

Create a script move.sh which contains this:

#!/bin/sh
mv $4 ../newdirectory/

Make it executable and then do this in the folder:

ls *.jpg | xargs -n 4 ./move.sh

This takes the list of filenames, passes four at a time into move.sh, which then ignores the first three and moves the fourth into a new folder.

This will work even if the numbers are not exactly in sequence (e.g. if some frame numbers are missing, then using mod 4 arithmetic won't work).

As suggested, you should use

seq -f 'frame-%g.jpg' 1 4 number-of-frames

to generate the list of filenames since 'ls' will fail on 280k files. So the final solution would be something like:

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

…will print the names of the files you need.

An easy way in perl (probably easily adaptable to bash) is to glob the filenames in an array then get the sequence number and remove those that are not divisible by 4

Something like this will print the files you need:

ls -1 /path/to/files/ | perl -e 'while (<STDIN>) {($seq)=/(\d*)\.jpg$/; print $_ if $seq && $seq % 4 ==0}'

You can replace the print by a move...

This will work if the files are numbered in sequence even if the number of digits is not constant like file_9.jpg followed by file_10.jpg )

Given masto's caveats about sorting:

ls | sed -n '1~4 p' | xargs -i mv {} ../destdir/

The thing I like about this solution is that everything's doing what it was designed to do, so it feels unixy to me.

Just iterate over a list of files:

files=( frame-*.jpg )
i=0
while [[ $i -lt ${#files} ]] ; do
  cur_file=${files[$i]}
  mungle_frame $cur_file
  i=$( expr $i + 4 )
done

This is pretty cheesy, but it should get the job done. Assuming you're currently cd'd into the directory containing all of your files:

mkdir ../outdir
ls | sort -n | while read fname; do mv "$fname" ../outdir/; read; read; read; done

The sort -n is there assuming your filenames don't all have the same number of digits; otherwise ls will sort in lexical order where frame-123.jpg comes before frame-4.jpg and I don't think that's what you want.

Please be careful, back up your files before trying my solution, etc. I don't want to be responsible for you losing a year's worth of data.

Note that this solution does handle files with spaces in the name, unlike most of the others. I know that wasn't part of the sample filenames, but it's easy to write shell commands that don't handle spaces safely, so I wanted to do that in this example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top