0

I have a bunch of video files where all the file names are un-useful gibberish.

1) Is there an easy command to change the names of all the files in a folder to a hash, like (sha256).mp4? I don't want to move / copy / modify any files, only rename them.

2) Can the command from 1) be modified to only add the hash onto the end of the original file name? Like (original name)_(sha256).mp4

I'm quite new to Ubuntu/Linux and would greatly appreciate an explanation for what each part of the command does.

  • Any command you can come up with to do it ONCE you can put a loop around to have it repeat it on a next file so the answer is yes. There is a command "rename" and a command "rename.ul" in linux to rename files. It does accept regexes and the normal variables to change a filename – Rinzwind Mar 1 at 15:02
2

You can actually do this with this rename command:

rename 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$new.mp4/' *mp4

To preview what it will do before actually renaming, use -n. For example:

$ ls
'my movie file01.mp4'  'my movie file05.mp4'  'my movie file09.mp4'
'my movie file02.mp4'  'my movie file06.mp4'  'my movie file10.mp4'
'my movie file03.mp4'  'my movie file07.mp4'
'my movie file04.mp4'  'my movie file08.mp4'

$ rename -n 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$new.mp4/' *mp4
my movie file01.mp4 -> 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496.mp4
my movie file02.mp4 -> 14f24228ead10d639ef3db11ea09c6216aa80879327a2a57fb549e6474fb05b0.mp4
my movie file03.mp4 -> 6c9ecec6a75e217fa1786dd6f920a5c1db8473f17447595e0d33d7fc3530453a.mp4
my movie file04.mp4 -> 96a29ae5bc3a5e35537bcea1068c746ddba205d17fcc8e522a52402c7ed69927.mp4
my movie file05.mp4 -> 189207823129b57e52c86a743ea7154f65b8eccb5182f322abc3aae35f14057d.mp4
my movie file06.mp4 -> 93be0fd15be56bb22af94a0a0aa272d56f61e77160f1170305d41166d6135913.mp4
my movie file07.mp4 -> 05c92b5632414f14445af3facdb0e187746b3b0f40bad94a5f351aeb7f9a8847.mp4
my movie file08.mp4 -> 0d3cf9c165d4c18af8922b8daa9a6b1031c6762d179fb910b968d60af9aed255.mp4
my movie file09.mp4 -> da04afebaec6ea3d43dc3a0e66b790ab13751b00fd81aa1f882986c097c36298.mp4
my movie file10.mp4 -> 47bf532970d3e759346462a85d15ab9d9171c5a7688a6e90a1e976e071ecd167.mp4

And, to keep the original name:

$ rename -n 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$_ $new.mp4/' *mp4
my movie file01.mp4 -> my movie file01.mp4 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496.mp4
my movie file02.mp4 -> my movie file02.mp4 14f24228ead10d639ef3db11ea09c6216aa80879327a2a57fb549e6474fb05b0.mp4
my movie file03.mp4 -> my movie file03.mp4 6c9ecec6a75e217fa1786dd6f920a5c1db8473f17447595e0d33d7fc3530453a.mp4
my movie file04.mp4 -> my movie file04.mp4 96a29ae5bc3a5e35537bcea1068c746ddba205d17fcc8e522a52402c7ed69927.mp4
my movie file05.mp4 -> my movie file05.mp4 189207823129b57e52c86a743ea7154f65b8eccb5182f322abc3aae35f14057d.mp4
my movie file06.mp4 -> my movie file06.mp4 93be0fd15be56bb22af94a0a0aa272d56f61e77160f1170305d41166d6135913.mp4
my movie file07.mp4 -> my movie file07.mp4 05c92b5632414f14445af3facdb0e187746b3b0f40bad94a5f351aeb7f9a8847.mp4
my movie file08.mp4 -> my movie file08.mp4 0d3cf9c165d4c18af8922b8daa9a6b1031c6762d179fb910b968d60af9aed255.mp4
my movie file09.mp4 -> my movie file09.mp4 da04afebaec6ea3d43dc3a0e66b790ab13751b00fd81aa1f882986c097c36298.mp4
my movie file10.mp4 -> my movie file10.mp4 47bf532970d3e759346462a85d15ab9d9171c5a7688a6e90a1e976e071ecd167.mp4

The explanation here is a bit complicated as it requires understanding some basic Perl. The main idea is:

  • my $new=`sha256sum "$_" | cut -d" " -f1` : this will run the command sha256sum on each input file ($_ is Perl magic for "current thing"), and cut to keep only the hash. To illustrate:

    $ sha256sum my\ movie\ file01.mp4 
    6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496  my movie file01.mp4
    $ sha256sum my\ movie\ file01.mp4 | cut -d" " -f1
    6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496
    

    The chomp() just removes the trailing newline from the command's output. The result is stored in the variable $new.

  • s/.*/$new.mp4/' : substitute everything (.*) with the $new name.

Or, for the other command:

  • s/.*/$_ $new.mp4/' : substitute everything with the original name ($_) followed by the new one.
  • does not work. rename -n 'chomp($new=sha256sum "$_" | cut -d" " -f1); s/.*/$_ $new.mp4/' *mp4 Global symbol "$new" requires explicit package name (did you forget to declare "my $new"?) at (user-supplied code). – Vijay Mar 1 at 17:55
  • @VeeJay wow, Ubuntu seems to have changed rename so that it runs with use strict! How strange. Thanks for the heads up, see updated answer. – terdon Mar 1 at 18:07
0

Tried and tested. For file names with spaces also.

1)

find . -maxdepth 1 -name '*.mp4' -print0 | while read -d $'\0' i ;do
    mv "$i" "`sha256sum "$i" | cut -d" " -f1`.mp4"
done

2)

find . -maxdepth 1 -name '*.mp4' -print0 | while read -d $'\0' i ;do
    mv "$i" "${i%%.mp4}-`sha256sum "$i" | cut -d" " -f1`.mp4"
done
  • With read, -d $'\0' is overkill, -d '' is the same thing. – Olorin Mar 5 at 6:58
-2

This needs a simple shell loop:

for i in *.mp4 ; do
    j="$(openssl dgst -sha256 \"$i\" | cut '-d ' -f2)"
    mv "$i" "$j.mp4"
done

The 2nd part of your question needs a little more work:

for i in *.mp4 ; do
    j="$(openssl dgst -sha256 \"$i\" | cut '-d ' -f2)"
    k="${i%%.mp4}"
    mv "$i" "$k_$j.mp4"
done
  • Works after removing the back slashes in \"$i\". – Vijay Mar 2 at 17:49

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.