I have a very large number of files with names of the format:
Schedule_20210109-235901.jpg
i.e. Schedule_DATE-TIME.jpg
The files are on average 3 seconds apart, I would like to write a bash script and select files spaced some large amount of time apart and rename them. I think I'll need a bash script with a for loop and an if statement, but I've never really used bash before.
For context, I've stored pictures for a web cam over the past 2 years and want to make a time lapse. However, at 3 second intervals this is mostly overkill as most days nothing happened in the workshop I was filming. I don't want to delete the unnecessary pictures or move large amounts of data.
My idea is to make a bash script that would add "use" to the start of the files say 30 second or 1 minute or even 1 hour apart. Then pass these to ffmepg. If I found times I would like to make more detailed videos of I could then do the same trick to pick them out.
I can't see how to do this with regular expressions or wild cards.
Any points much appreciated.
2 Answers 2
You can select any files based on your 'interval' logic, copy them, rather than rename, to a new directory and run ffmpeg
for them. It's better than my initial thought to feed ffmpeg
with a stream of arguments -i file
which, besides hacky, could have some limitations like the shell command's length.
Here is an example, to get one every 10 pictures, starting from the first. Their order is alphabetical ascending, so it is by the filename timestamp:
printf '%s\n' Schedule_* | awk 'NR%10==1' | xargs cp -t temp/ --
or using GNU arguments zero separation, to generalize for filenames:
printf '%s0円' Schedule_* | awk 'NR%10==1' RS='0円' ORS='0円' | xargs -r0 cp -t temp/ --
Here is another way for selecting them. You can isolate the timestamp, see this example:
printf '%s\n' Schedule_* | awk '{print substr(0,10,15ドル)}'
returning 20210109-235901
etc. And you can use it to filter a lot of filenames in different ways. For example, get only one image per hour (the first one, if any images exist for this hour):
printf '%s\n' Schedule_* | awk '!seen[substr(0,10,11ドル)]++'
or get only one image for every minute:
printf '%s\n' Schedule_* | awk '!seen[substr(0,10,13ドル)]++'
Also you can add start and end time for your file selection. For example, get the first image of every hour for a time period:
printf '%s\n' Schedule_* | awk '
substr(0,10,15ドル)>"202201" && substr(0,10,15ドル)<"20220201-12" && !seen[substr(0,10,13ドル)]++
'
For all cases, we pipe the arguments to xargs
- cp
so later we can run ffmpeg
with its globbing option into the temporary directory.
-
You can also use
mv
instead ofcp
(if space matters),mv -t some/dir/ --
do yourffmpeg -pattern_type glob -i '*.jpg'
but you will have to move them back to the original directory. Repeat process to try different selections, make different videos.thanasisp– thanasisp2022年06月03日 07:33:57 +00:00Commented Jun 3, 2022 at 7:33
I think to rename all pictures with bash script i don't think can work based on my personal experience iv done similar process to add time stamp i think you can also add your own stamp next to the each file by using AWK in bash script or rename utility
for example
rename uppercase files to lowercase.
rename 'y/A-Z/a-z/‘ *
To remove a file extension from a bunch of files, use the following syntax. This example will remove the .bak extension.
rename 's/\.bak$//' *.bak
here is reference below https://linuxconfig.org/how-to-rename-multiple-files-on-linux
ffmpeg ... Schedule_????????-??0001.jpg
(assuming there's a snap at 01 seconds past most minutes)