8

I have many files with different names of different lengths. Extension of these files are jpeg.

How to change names of the files to random generated names?

3 Answers 3

9

Run in the directory with the files:

for file in *.jpeg; do
    mv -- "$file" "$RANDOM.jpeg"
done

But there is a chance the random names will conflict since $RANDOM only gives numbers between 0 and 32767.

Better solution, thanks to pbhj:

for file in *.jpeg; do
    mv -- "$file" "$(mktemp --dry-run XXXXXXXX.jpeg)"
done

There is still a chance the random names will conflict, but it's significantly smaller with 8 alphanumeric characters from mktemp. See Anselmo's answer for guaranteeing no conflicts.

5
  • 2
    I wouldn't use $RANDOM which defaults to 5 digit numbers; instead I'd try mktemp --dry-run XXXXXXXX.jpg, 3 or more Xs get replaced by a random alphanumeric string of equal length.
    – pbhj
    Jan 4, 2019 at 20:47
  • In the proposed version, we can also string: mv "$file" "$RANDOM.jpeg" replace by string: mv "$file" "$( gpw 1 20 ).jpeg" or another string: mv "$file" "$( pwgen 20 1 ).jpeg". Where 20 - is number of characters in the file name.
    – Denis
    Jan 4, 2019 at 20:57
  • 1
    @pbhj Thanks for mentioning! I'll add that in. Yeah, mine is a pretty lazy (but simple) solution.
    – wjandrea
    Jan 4, 2019 at 21:12
  • --dry-run here is on mktemp not on mv => files will be actually renamed :)
    – jave.web
    Feb 26, 2022 at 19:01
  • Why use --dry-run at all? By passing it, you risk a clash and then you silently overwrite one of your earlier files. Not good. Just omit it, then mktemp can guarantee you a unique destination filename. That's the whole point of it. The only exception is if you've exhausted all possible combinations from the XXXXXXX pattern
    – carpii
    Apr 1, 2022 at 0:40
4

Using RANDOM is a limited approach. From BASH man: "RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated." So... No more than 32768 files! : )

Another, bigger, problem is the possibility of repetition. You see, the problem of repetition affect any use of random generators, only with different probability of occurrence.

The use of mktemp can be a much better solution, but you must not use the --dry-run parameter, because this generate the name but does not guarantee that a file with that name doesn't exist. Used in that way it became only a kind of random generator.

So, my simple propose is:

for file in *.jpeg; do
    new_file="$(mktemp XXXXXXXX.jpeg)"
    mv -f -- "$file" "$new_file"
done

Step by step.

new_file="$(mktemp XXXXXXXX.jpeg)"

Running mktemp that way, it creates a file safely with a new random name, caring random repetition. It also output the name of the created file, that I catch in new_file.

mv -f -- "$file" "$new_file"

Running the mv with the -f force the renaming of the image to overwrite the new_file.

2
  • 1
    Huh, I didn't realize --dry-run doesn't guarantee a unique file name. The manual isn't very clear about that - just says it's "unsafe" but doesn't define what "unsafe" means. Thanks!
    – wjandrea
    Jan 7, 2019 at 14:33
  • 1
    @wjandrea It only guarantees a name is free at the exact time of checking, but doesn't protect it until the time of use from being taken by other programs. It could even issue the same name again itself if you haven't created the first yet as it's still free. Also a security risk: en.wikipedia.org/wiki/Time-of-check_to_time-of-use Dec 16, 2022 at 17:34
3

You can do this easily with a large degree of certainty that you won't get file names with similar names by having multiple$RANDOMs as follow:

for file in *.jpeg; do
    mv -- "$file" "$RANDOM-$RANDOM-$RANDOM.jpeg"
done

The possibility of getting the same name is 1/(32767)^3 in the above example.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .