0

I have a script that randomizes filenames with the JPEG extension:

#!/bin/bash for img in *.jpg; do newname=$(head /dev/urandom | tr -dc a-z0-9 | head -c 8) mv "$img" "$newname".jpg; done

This script, when used with JPEG files, outputs filenames such as the following:

0cb1v984.jpg dqm2xxoj.jpg o61bg4n5.jpg

However, when I try to replace the ".jpg" extension in this bash script with ".gif" or ".webp" it doesn't work.

Is the problem due to the GIFs and WEBPs I'm attempting to rename being animated GIFs and WEBPs?

Ideally I'd like one bash script that can randomize the filenames of files with any of these 3 extensions, but I'd be fine to have 3 different bash scripts to randomize the filenames of each extension.

I've fiddled around with the most upvoted answer to this question, to no avail.

whitewings
  • 2,457
  • Please edit your question and show us the exact command you are running that "doesn't work" along with the working one. The issue is most definitly not GIFs being animated. – Panki Aug 10 '22 at 19:33
  • The tempfile command can create arbitrary files in a user-determined directory and with a user-determined prefix and suffix. Perhaps you could capture the name and move your file to it. – MDeBusk Aug 10 '22 at 19:35
  • Silly question, but did you replace both occurences of jpg in your onliner when trying a different filetype? – Panki Aug 10 '22 at 19:37

1 Answers1

1

Just needs another for loop to cycle through the extensions.

for ext in jpg gif webp; do
  for img in *.${ext}; do
    newname="$(head /dev/urandom | tr -dc a-z0-9 | head -c 8).${ext}"
    mv "$img" "$newname"
  done
done

But there are a few issues with your method.

  • Inefficiency at scale -- better to generate random data in bulk and snip off 8 characters at a time
  • Possibility for name clashes (quite unlikely but not impossible)
  • Possibility /dev/urandom won't deliver 8 alphanumerics in the first ten "lines" (also quite unlikely but also not impossible)

So here's an improved version

# give our variables global scope
declare data=''
declare newname

rand() {

check if data contains the required # of characters...

if [ -z "${data:${1}}" ] ; then # ...if not, generate 1000 more characters data="${data}$(tr -dc a-z0-9 < /dev/urandom | head -c 1000)" fi

fill the nominated variable with the required number of characters

eval "${2}"="${data:0:${1}}"

remove the characters just used from the random data

data="${data:${1}}" }

for ext in jpg gif webp; do for img in *.${ext}; do while true ; do rand 8 newname # keep getting $newname values until $newname.$ext doesn't exist [ -e "${newname}.${ext}" ] || break done mv "${img}" "${newname}.${ext}" done done

On my machine, this version took ~11 seconds to process 1500 files, vs ~25 seconds for the less efficient version.

bxm
  • 4,855