0

I'm trying to create a script that renames a group of files. Normally they will be TIFs but sometimes an occasional oddball could be thrown in so I would like to rename the file and ignore the file extensions.

The file names will all be the same with the epoch time thrown in the middle as a differentiator. The end result will be similar to this:

Name1=CLMSFILE

Name2=Epoch

Name3=_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES

CLMSFILE53253_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES.TIF (or other extension)

This is what I currently have

#Rename files and insert epoch time
name1=$CLMSFILE
name2=$(date  +%s%3N)
name3=$_A\ BUNCH\ OF\ OTHERTEXT_WITH_A_MIXTURE\ OF\ UNDERSCORES\ AND_SPACES

for f in *; do
  newname=$name1$name2$name3
  mv -n "$f" "${newname}"
done

After running this I only get the first file renamed except it ignores the first variable and there is no extension.

1653049404956 _A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES
220220217SOMEORG20003_01.TIF
220220217SOMEORG30004_01.TIF
0

1 Answer 1

0

There are several problems in your shell script that lead to the errors you observe:

  1. You say that the first name part is to be CLSMFILE. However, in the variable assignment you state name1=$CLMSFILE, so you assign to the first part the content of a shell variable named CLSMFILE, which likely doesn't exist and therefore is empty. The same is actually also true for the name3 part, but you happen to start the string with an _, and $_ has a special meaning in the shell so interpretation stops immediately after the _ and the remaining part of the string is imported unchanged to your variable.

  2. Your script would try to rename all files to the same name. Luckily, you used the -n option, or you would have lost all but the last of the files in your directory.

    The reason is that the date command in name2=$(date ...) is only evaluated at the moment the assignment is made, not every time the $name2 variable is used. So it is constant for all iterations of the loop.

  3. You state that you want to have a filename extension, but you forgot to add an extension to the file. mv renames the entire filename, not only the part before the ., simply because more than one . is allowed in filenames.

I would recommend that you use shellcheck, also available as standalone tool, to catch errors in shell scripts.

The following modification should work:

name1="CLMSFILE"
name3="_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES"

for f in *; do
  basename=${f%.*}
  newbasename="$name1$(date  +%s%3N)$name3"
  newname=${f/$basename/$newbasename}
  mv -n "$f" "${newname}"
done

This uses shell string manipulation to

  • store the "basename" part of $f, i.e. everything up to the last .-separated part, in a variable $basename
  • generate the new basename according to your rule, but run the date command for every loop iteration
  • replace the $basename sub-string of $f with $newbasename
  • rename the file accordingly

Ideally, you would replace the mv -n ... part with something like

echo "Renaming '$f' to '$newname'"

until you are sure that the name-generating logic works correctly.

0

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.