3

I am trying to prefix timestamp and add an extension to files using a script. I have file ABC which I is being renamed to ABC.txt

DIRECTORY=`find /path/to/file -type f ! -name "*.*"`
NOW=$(date +%Y-%m-%d-%H%M%S)

for file in $DIRECTORY; do

    mv "$file" "$file"_"${NOW}.txt"
    done

The output above works but as a suffix, if I switch it around

    mv "$file" "${NOW}"$file".txt"

I'm getting cannot mv: cannot move`2019-10-18-231254/path/to/file/ABC.txt': No such file or directory

I can see the issue is with the $Directory as this is calling the full path when doing the mv. Could someone please help simplify this?

1
  • 1
    You can get the filename from a path like this: stackoverflow.com/a/965072/2519977. This may be a duplicate. The problem is that $file contains the whole path and not just the filename. If everything is happening in the same folder, the filename should suffice - if not you'd also have to extract the path. Or maybe sed could help as well...
    – rudib
    Oct 18 '19 at 22:37
3

I'd suggest avoiding the loop over the find command's output for the reasons discussed here:

Instead, consider using -execdir, with a shell one-liner to remove the path components:

#!/bin/bash

export NOW=$(date +%Y-%m-%d-%H%M%S)

find /path/to/file -type f ! -name '*.*' -execdir sh -c '
  for f; do echo mv "$f" "${NOW}_${f#./}"; done
' find-sh {} +

Remove the echo once you are happy that it is doing the right thing. Note that NOW needs to be exported so that its value is available in the sh -c subshell.

If your find implementation doesn't provide -execdir, then you can use -exec if you remove and replace the path explicitly:

find /path/to/file -type f ! -name '*.*' -exec sh -c '
  p="${1%/*}"; echo mv "$1" "$p/${NOW}_${1##*/}"
' find-sh {} \;
2
  • Great thanks for the help, It's prefixing as i required.
    – Samosa
    Oct 18 '19 at 23:14
  • thank, it help me. In my case, my need is just to add timestamp prefix to archive files: horodate_prefix=$(date +%Y%m%d_%HH%M) export file_name=${horodate_prefix}_save.tar.gz echo $file_name # create tar tar zcvf $file_name *.ext
    – bcag2
    Jan 22 '20 at 9:42
1

Using GNU Parallel:

find /path/to/file -type f ! -name "*.*" -print0 |
  parallel -0 mv {} {//}/$(date +%Y-%m-%d-%H%M%S)_{/}.txt

Please consider using ISO8601 for timestamps:

find /path/to/file -type f ! -name "*.*" -print0 |
  parallel -0 mv {} {//}/$(date +%Y-%m-%dT%H:%M:%S)_{/}.txt

Or:

find /path/to/file -type f ! -name "*.*" -print0 |
  parallel -0 mv {} {//}/$(date +%Y%m%dT%H%M%S)_{/}.txt

That means you can use a standardized ISO8601 parser for parsing the timestamp later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.