In which I shoot myself in the foot, and then fix it with a shell script.

I don’t make a secret out of my long-running MMO habit, at least on this blog.  I tend not to mention it in polite circles, because an MMO habit is one step above admitting that you are a heroin enthusiast, but nothing about the internet is particularly polite.

My policy of late has been to drop MMOs at the point where I realize that I am simply logging on to Make The Numbers Bigger, and not because I am enjoying the game or the people I play with.  I do tend to keep a bunch of screenshots around, however, so I can occasionally go back and look through them to remember when these were cutting edge graphics:

Everquest’s sharks were prone to transcending their watery limitations, at least in the early days.

One slight problem is that I tend to get a ton of screenshots after a while, and if I move from device to device to play on then the screenshots tend to get jumbled up and out of order.  One way to work around this is to toss them all in a directory and sort it by date.

Except.

Recently, I was working to clear documents and pictures off a couple of Windows PCs, and did so by uploading everything to iCloud Drive and then deleting it from the PCs.  I did not realize that one of the TINY INCONSEQUENTIAL QUIRKS of iCloud Drive on a PC is that it updates the time/date stamp on the file to the date uploaded.

So this is what a folder of screenshots from FFXIV looked like:

OK, so.  This is less than optimal, but there’s still timestamp information. It’s just in the file names rather than the metadata. Surely I can work with this.

So after a fair bit of hard work browsing StackExchange, I came up with this.  No guarantees that this will work for anyone other than me. I stole most of it from other people without properly understanding what they were doing.

#!/bin/bash
#
#
# fixdates
# reads dates in filenames and tries to set the file date from the date stamp in the name
#
# character replacement stolen from https://stackoverflow.com/questions/2871181/replacing-some-characters-in-a-string-with-another-character
# dash escape stolen from https://superuser.com/questions/528162/how-to-escape-in-bash
# relies on all single digit days and months having leading 0s.


for filename in *.*
do
	# Set up our variables
	year="2000"
	month="01"
	day="01"
	hour="12"
	minute="00"
	second="00"
	fulldate="20000101"
	fulltime="000000"
	filegood=0
	
	# drop the extension.  May break with filenames with multiple periods?
	filenamenoext=${filename%.*}

	# drop dashes
	filenamenodash=$(echo $filenamenoext | tr -d "-")

	# replace underscores with spaces
	filenamespaced=$(echo $filenamenodash | tr _ " ")
		
	# this will replaces both dashes and underscores but let's leave that aside for now:
	# filenamespaced=$(echo $filenamenoext | tr -- -_ " ")
	# and yes the -- is important since it says "there are no more options after this point, treat the dash you're about to see as a character"
	
	# break the extensionless filename into components by space
	
	read -ra filenamearray <<<"$filenamespaced"
	
	for i in "${filenamearray[@]}"
	do
		itemsize=${#i}
		if [ "$itemsize" == "8" ] && [ "$itemsize" -eq "$itemsize" ]; # cheap way to check if something is a number
		then
			fulldate=${i}
			((filegood++)) # we have a date, touch is go
		fi
		if [ "$itemsize" == "6" ] && [ "$itemsize" -eq "$itemsize" ];
		then
		# we have a time? probably
			fulltime=${i}
		fi
		if [ "$itemsize" == "14" ] && [ "$itemsize" -eq "$itemsize" ];
		then
#			This looks like date and time in one string.
#			We're going to assume date first because otherwise is madness
			fulldate=${i:0:8}
			fulltime=${i:8:6}
			((filegood++))
		fi
	done

	if (( filegood == 1 )); # We think we at least have a date
	then
		if [ "${fulldate:4:2}" == "19" ] || [ "${fulldate:4:2}" == "20" ];
		then
			year="${fulldate:4:4}"
			month="${fulldate:0:2}"
			day="${fulldate:2:2}"
		else
			year="${fulldate:0:4}"
			month="${fulldate:4:2}"
			day="${fulldate:6:2}"
		fi
		hour="${fulltime:0:2}"
		minute="${fulltime:2:2}"
		second="${fulltime:4:2}"
	touch -d "$year"-"$month"-"$day"T"$hour":"$minute":"$second" "$filename"
	else
	echo "Bad file (Couldn't find anything that looks like a date):" "$filename"
	fi
done

And this, for the time being, seems to work and I have my screenshots back to the proper times and dates.

Also, it’s generic enough that it worked for files with their time stamps in the following formats:

gsdx_20170411131943.bmp
Kandagawa Jet Girls 2022-05-23 23-24-14.mp4
ffxiv_09242015_191807.png

But there’s little to be done for uPlay unless I massage the filenames manually first or figure out how to parse the entire string for “2019” or “2020” and then extract the date from that point and add leading zeros to the single-digit entries and… look, Ubisoft, would it have killed you to write your dates in a little more sensible manner?

Assassin's Creed® Unity2019-4-17-15-33-0.png
Tom Clancy's The Division® 22019-10-4-2-25-9.jpg

Also a space between the game title and the date would have been cool.

But gosh dang it, I have the world’s hugest sense of satisfaction right now.

This entry was posted in shell scripts. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.