I am not a shell expert and I would like to know how to write a small algorithm (I think it is possible) to solve my problem.
I have an output
directory which itself contains several folders for example data_1
, data_2
, etc. These folders also contain different versions, for example version_1
, version_2
. And finally these versions all contain an image folder photos
which contains several thousand images in the form 000001.jpg
, 000002.jpg
, ...
I'm looking to convert all these photos
folders into a video that takes the photos frame by frame. For example for the 2nd version of the dataset data_1
I will do the following commands:
ffmpeg -i data_1/version_1/photos/m.jpg data_1/version_1/data_1_ version_1.mov
rm -r data_1/version_1/photos
But this implies that I have to rewrite by hand the command once the program is finished for a folder by changing the folder names and also the .mov file which must imperatively be of the form data_version.mov and saved at data/version/data_version.mov.
I would like a script that automates this procedure by going through all the data
folders to create the videos BUT also by checking that if the video exists the script is not run on the current version
.
Thank you in advance for any help
CodePudding user response:
Assuming the directory name photos
is fixed, would you please try:
while IFS= read -r dir; do # assign "dir" to the path to "photos"
dir2=${dir%/photos} # remove trailing "photos" dirname
name=${dir2#*/} # remove leading slash
name=${name//\//_} # convert slashes to underscores
echo ffmpeg -i "$dir/m.jpg" "$dir2/${name}.mov" # execute ffmpeg
echo rm -rf -- "$dir" # rm "photos" directories
done < <(find . -type d -name "photos") # find dir named "photos" recursively
If the output looks good, drop echo
and execute.
CodePudding user response:
I would go with a glob expansion instead of using find
, as its easier and more portable to force a specific path; the rest would be almost identical as @tshiono answer.
shopt -s nullglob extglob
photos_dirpaths=(data_ ([[:digit:]])/version_ ([[:digit:]])/photos/)
if [ ${#photos_dirpaths[@]} -eq 0 ]
then
echo 'error: run this script inside the output directory' 1>&2
exit 1
fi
for dirpath in "${photos_dirpaths[@]%/}"
do
filepath="${dirpath%/photos}"
filename="${filepath//\//_}.mov"
echo ffmpeg -i "$dirpath/m.jpg" "$filename"
# or?
echo ffmpeg -i "$dirpath/m.jpg" "$filepath/$filename"
[ $? -eq 0 ] && echo rm -rf "$dirpath"
done