You are not logged in.

#1 2012-11-03 16:38:51

whoops
Member
Registered: 2009-03-19
Posts: 793

Small metatag / file renaming script: what "stuff" should I be using?

Hi!

I need a small script that moves all videos, images and other files in a folder to

./year-month/day-hour-minute-seconds_originalfilename.ext

The date/time is supposed to come from the meta tags if the file has its own timestamp and from the file stats (creation date) if no meta data is available.

Now, this is how I would usually do something like this:
1) Install exiv2 and mediainfo and various other cli-tools that can extract timestamps from file meta data.
2) Mess around with those programs until after piping the output trough about 200 grep's and sed's I get a line of bash for everything I need.
3) Stick those lines together somehow into one huge mess consisting basically of just one single giant line of bash that inexplicably does the job
4) Instantly forget how it works and somehow accidental mess up my whole system the next time I try to modify & execute the script.

I already almost finished a bash script that works like that. And broke it. And don't understand how it works any more, so I was about to start over... but at the moment I guess I might have just enough spare time to do it right instead... so...

- What's would be the "right" way to do something like this?
- Should I just learn how to use functions instead of pipes or forget about bash and try python?
- Still use regex to fiddle it together or use something that can handle date/time as actual date+time instead of putting it into a string?
- Use various external tools (like exiv2 and mediainfo from the repos) or take something that has... uhm... API's or something... to handle... tag stuff itsself?
- What language / tools / methods would a programmer that knows all there is to know choose for a job like this?

I've written a lot of small scripts and a few "programs" in the past but never really got around to learn programming... for some reason I just got used to do everything I needed with only a few functions, loops and a lot of trying around + copy&paste somehow even if the code gets insanely awkward & impractical... so... I have no idea where to start looking for a "good" solution to this problem.

Any hints?
Thx!

Offline

#2 2012-11-06 08:18:14

whoops
Member
Registered: 2009-03-19
Posts: 793

Re: Small metatag / file renaming script: what "stuff" should I be using?

Ok, been looking around a lot. C / C++ both are overkill I guess. Couldn't find all the python functions I need to do that program in a really clever way (when I try, it looks mostly like my bash scripts. Just even clumsier). And Java probably isn't meant to do small shell tools like that...

Would PHP be a good choice? I like the easy array + string handling and the easy way to fall back to bash or other languages & tools any time I'm stuck... it looks a lot less messy than how I'm usually working, but I still feel like I'm doing regex substitutions instead of proper file/variable handling etc. way too often.

Last edited by whoops (2012-11-06 08:19:04)

Offline

#3 2012-11-06 10:30:46

foppe
Member
Registered: 2011-04-02
Posts: 47

Re: Small metatag / file renaming script: what "stuff" should I be using?

Nothing wrong with bash if you can find cli applications that can do the data-extraction.
You can put the filenames in a file and easily loop through them in bash.

ls -1 > files.txt

for movie in files.txt
do
    # Logic goes here
    # You use the variable $movie
done

So you basically write the logic for moving / renaming one file and apply that on the whole folder.

Good luck

Offline

#4 2012-11-06 10:44:12

whoops
Member
Registered: 2009-03-19
Posts: 793

Re: Small metatag / file renaming script: what "stuff" should I be using?

Hmm... thanks, yes, I guess putting stuff in files instead of piping and looping everything around could make my bash scripting a whole lot less messy.

But isn't "regexing" output from other cli applications around like I usually do considered bad "programming"? I thought that should be avoided because it can lead to strange semi-unpredictable behaviour if the output format of the application changes with an update and things like that... at least that's what usually happens when I wrote the script :3

So if I understand right, it would still be a good option to just stick to bash and then simply just rewrite & optimize the script until it's not as much of a mess?

Last edited by whoops (2012-11-06 10:44:24)

Offline

#5 2012-11-06 10:51:22

foppe
Member
Registered: 2011-04-02
Posts: 47

Re: Small metatag / file renaming script: what "stuff" should I be using?

You should do the output with `date`. It's very uncomplicated with the input and has extraordinary output possibilities

date --date="2012/10/11 11:47" +%Y-%m/%d-%H-%M-%S
# 2012-10/11-11-47-00

Offline

#6 2012-11-30 14:03:17

whoops
Member
Registered: 2009-03-19
Posts: 793

Re: Small metatag / file renaming script: what "stuff" should I be using?

Argh, I tried - seems to work but I made a mess again and just looking at it confuses me. It's not as bad as usual, but still...:

(replaced the mv's + mkdir's by echo's for "debugging" purposes:)

#!/bin/zsh
pushd "$1" && {
	basefolder=$(readlink -fn "$1")
	find ./ -type f -print0 | sort | while read -d $'\0' file
		do
		echo -n "#"
			unset year minute hour day month TIME second newname fname dname debout part1 part2 part3
			fname=$(basename "$file")
			dname=$(dirname "$file")

filethm=$(echo $file | sed "s/...$/THM/")

			file "$filethm" | grep -q "image" && {
				exiv2 pr "$filethm" | grep -a stamp | sed "s/.*\(....:..:.. .*\)/\1/" | sort | grep -Ev "[[:alpha:]]" | head -n1 |\
				 IFS=" -:" read year month day hour minute second bla bla bla;
				debout="INFO for $file pulled from $filethm: $year-$month-$day $hour-$minute-$second" 
				}

			part1="$year-$month-$day"
			part2="$hour-$minute-$second"
			echo "$part1 - $part2" | grep -q -E "^[1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] - [0-2][0-9]-[0-5][0-9]-[0-5][0-9]" ||\
			{
			file "$file" | grep -q "image" && {
				exiv2 pr "$file" | grep -a stamp | sed "s/.*\(....:..:.. .*\)/\1/" | sort | grep -Ev "[[:alpha:]]" | head -n1 |\
				 IFS=" -:" read year month day hour minute second bla bla bla;
				}

			part1="$year-$month-$day"
			part2="$hour-$minute-$second"
			echo "$part1 - $part2" | grep -q -E "^[1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] - [0-2][0-9]-[0-5][0-9]-[0-5][0-9]" ||\
			{
			mediainfo "$file" | grep -q date && {
				mediainfo "$file" | grep -a date | sed "s/.*\(....-..-.. .*\)/\1/" | sort | grep -Ev "[[:alpha:]]" | head -n1 | IFS=" -:" \
					read year month day hour minute second bla bla bla;
			}
				}
			}

unset IFS
			part1="$year-$month-$day"
			part2="$hour-$minute-$second"
			part3=$(echo $fname | sed "s/^[0-2][0-9]-[0-5][0-9]-[0-5][0-9]_//");
			echo "$part1 - $part2" | grep -q -E "^[1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] - [0-2][0-9]-[0-5][0-9]-[0-5][0-9]" ||\
				{ 
				debout="$debout No meta data for $file ($part1-$part2), taking creation date + filename: "
				# Get year-month-day
				part1=$(stat -c%y "$file" | awk -F " |:|\\\.|-" '{printf $1"-"$2"-"$3}')
				# Get hour-minute-second
				part2=$(stat -c%y "$file" | awk -F " |:|\\\.|-" '{printf $4"-"$5"-"$6}')
				debout="$debout ${part1}/${part2}_${part3}";
				}
			# Destination filename
			newname=./${part1}/${part2}_${part3};

			[ "$newname" != "$file" ] && {\
				echo $debout; 
				if ! [ -d $(dirname "$newname") ]
					then echo mkdir -p $(dirname "$newname") -v
				fi
			echo mv "$file" "$newname" -v --backup=numbered
			}
		done
}
popd

Also, for some reason it doesn't work with bash. Only zsh. No idea why.

I just have accumulated too many bad habits with bash I guess... Any hints on how I should proceed now?
Throw the whole script away and try to learn python? xD

Last edited by whoops (2012-11-30 14:05:33)

Offline

#7 2012-11-30 16:14:37

GogglesGuy
Member
From: Rocket City
Registered: 2005-03-29
Posts: 603
Website

Re: Small metatag / file renaming script: what "stuff" should I be using?

exiv2 already has builtin functionality to rename files:

exiv2 -r %Y_%m_%d_%H%M%S rename *.JPG

Offline

Board footer

Powered by FluxBB