using stat to provide timestamp for touch

stat's output is a Unix timestamp, also called seconds since the Epoch.

All GNU coreutils that accept a date allow you to put a timestamp instead by prefixing the timestamp with an @.

So try this

touch -d @$ORIGTS $f

See coreutils - Seconds since the epoch


touch can use a file's timestamp using the -r option. You might want to output to a different file (I assume below that -if is input file and -of is output file)

for f in ...; do
    sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
    touch -r $f $f.new
    mv $f.new $f
done

IFS=$(echo -en "\n\b")

Since you're assuming a shell with echo -e, and you have bash in your shebang line anyway, you can use IFS=$'\n\b'. Making backspace a separator is rather weird. You don't need IFS for what you're doing anyway.

OLDIFS=$IFS

IFS=$OLDIFS

Note that this restores the old value of IFS only if IFS was initially set. If IFS was initially unset, this sets IFS to the empty string, which is completely different. In ksh, bash or zsh, if you need to set IFS temporarily, you can write your code in a function and make IFS local to this function. In other shells, you need to be careful about the unset case.

`find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`

Never use command substitution on the output of find.

  • This splits the output at the characters in $IFS. If you set IFS to a newline, then this splits the output at newlines, but you still can't handle file names containing newlines.
  • Not only is the result of command substitution split into words, but then each word is used as a glob pattern. If you files called A[12].pdf, A1.pdf and A2.pdf, you'll end up with A1.pdf A2.pdf A1.pdf A2.pdf. You can turn globbing off with set -f (and back on with set +f), but here (like most of the time) the right way is not to use command substitution.

Use the -exec argument to find (or if your system has -print0, you can use find … -print0 | xargs -0 … instead; this is only useful to act on multiple files at once if you need portability to ancient Linux systems or current OpenBSD systems that have -print0 but not -exec … {} +).

ORIGTS=`stat -c "%Y" $f`
# [transform $f]
touch -t $ORIGTS $f

Note that you're missing double quotes around $f (they aren't needed if these are the results of splitting and you haven't changed IFS since then and globbing is turned off, but really, always put double quotes unless you know why you can't leave them on).

This is clumsy and non-portable (stat doesn't exist on all systems, and its arguments are different across the different systems where it exists). touch has a portable option to set a file to the timestamp of another file: touch -r REFERENCE_FILE FILE. I would recommend one of two approaches instead:

  • If you can, first transform the original file into a new file, then call touch -r to set the date of the new file, and finally move the new file into place. It's better to make sure the output is fine before anything happens to the input; otherwise, if the transformation is interrupted for any reason (e.g. a power failure), you'll lose data.
  • If the transformation is a black box that you have no control over, you can use touch -r twice: once to save the date of the original file on an empty temporary file (which will be automatically created), then again after the transformation to restore the date using the temporary file.

Thus:

find /mnt/library/Libra/Libra/Ashfords -name '*.pdf' \
     -exec sh -c 'transform "$0" to "$0.tmp" && touch -r "$0" "$0.tmp" && mv -f "$0.tmp" "$0"' {} \;