Most unices don't track a file's creation date¹. “Creation date” is ill-defined anyway (does copying a file create a new file?). You can use the file's modification time, which is by a reasonable interpretation the date at which the latest version of the data was created. If you make copies of the file, make sure to retain the modification time (e.g. cp -p
or cp -a
if you use the cp
command, not bare cp
).
A few file formats have a field inside the file where the creator application fills in a creation date. This is often the case for photos, where the camera will fill in some Exif data in JPEG or TIFF images, including the creation time. Nikon's NEF image format wraps around TIFF and supports Exif as well.
There are ready-made tools to rename image files containing Exif data to include the creation date in the file name. renaming images to include creation date in name shows two solutions, with exiftool and exiv2.
I don't think either tool lets you include a counter in the file name. You can do your renaming in two passes: first include the date (with as high resolution as possible to retain the order) in the file name, then number the files according to that date part (and chuck away the time). Since modern DSLRs can fire bursts of images (Nikon's D4s shoots at 11fps) it is advisable to retain the original filename as well in the first phase, as otherwise it would potentially lead to several files with the same file name.
exiv2 mv -r %Y%m%d-%H%M%S:basename: *.NEF
# exiv2 uses `strftime(3)`, so `%Y%m%d-%H%M%S` returns YYYYMMDD-hhmmss
# :basename: is a naming variable exiv2's `-r`-handle provides. See `exiv2 -h` for more
# Now you have files with names like 20140630-235958_DSCC1234.NEF.
# Note that chronological order and lexicographic order agree with this naming format.
i=10000
for x in *.NEF; do
i=$((i+1))
mv "$x" "${x%-*}_FOO_${i#1}.NEF"
done
${x%-*}
removes the part after the -
character. The counter variable i
counts from 10000 and is used with the leading 1
digit stripped; this is a trick to get the leading zeroes so that all counter values have the same number.
Rename files by incrementing a number within the filename has other solutions for renaming a bunch of files to include a counter.
If you want to use a file's timestamp rather than Exif data, see Renaming a bunch of files with date modified timestamp at the end of the filename?
As a general note, don't generate shell code and then pipe it into a shell. It's needlessly convoluted. For example, instead of
find -name '*.NEF' |
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' |
bash
you can write
find -name '*.NEF' |
gawk 'BEGIN{ a=1 }{ system(sprintf("mv %s %04d.NEF\n", $0, a++)) }'
Note that both versions could lead to catastrophic results if a file name contained shell special characters (such as spaces, '
, $
, `
, etc.) since the file name is interpreted as shell code. There are ways to turn this into robust code, but this isn't the easiest approach, so I won't pursue that approach.
¹ Note that there is something called the “ctime”, but the c
isn't for creation, it's for change. The ctime changes every time anything changes about the file, either in its content or in its metadata (name, permissions, …). The ctime is pretty much the antithesis of a creation time.
Best Answer
You can use the
-g
flag to output only the property you're interested in, and-Pv
to print the value without any surrounding fluff. The result is easy to parse.It may also be helpful to change the file date to match the image date:
exiv2 -T DSC_01234.NEF
.