I have a md5sum list and a lot of file which I wanted to checksum and then rename them according to the md5sum list.

Example of the list:

d4cd401ade018617629b39efed7b7be4  foo.bar
8fdb07ca55c164e0d5a69eff49fe800e  bar.foo
8b167d01009f066aaf2d6c1ba336d842  foobar

Now I wanted to checksum every files in current directory, if the checksum are matched with the list above then rename it as the right colum.

How I can do that?


4 Answers 4


First of all, I'm not going to claim that this is the most profound solution but, here is one way to do it.

Let's say you have the file with the checksum and filenames called filelist.txt then you could use something like:

while read -r checksum fname; do for f in file*; do if [[ $checksum == $(md5sum "$f" | cut -d' ' -f1) ]]; then mv "$f" "$fname"; fi ; done ; done < filelist.txt
  • I got error "md5sum: file*: No such file or directory"
    – minhng99
    Commented Dec 7, 2016 at 10:47
  • 1
    You got the error because file* does not exist. Change file* to * and it should work. The latter will loop through all files within the directory. Commented Dec 7, 2016 at 11:11

I haven't fully tested, it's just theoretically working. Substitute where needed:

#! /bin/bash
for II in *
    if [ -f "$II" ]; then
        TMPV=$(md5sum "$II")
        MD="${TMPV%\ \ *}"
        TMPV=$(grep "$MD" hashes.txt)
        if [ ! -z "$TMPV" ]; then
            FN="${TMPV#*\ \ }"
            echo "Found: $II"
            echo "MD5 is: $MD"
            echo "Which matches $FN in hashes database"
            echo "Will Rename $II TO $FN"
            echo ""
            # CAREFUL, RENAME CMD: mv "$II" "$FN"

As I say, haven't tested it, but it seemed to work on my box.


My idea:

  1. At first you need to sort your known checksums: sort checksums.txt > sorted_checksums.txt
  2. Generate file for all existing files and also sort them: md5sum * | sort > real_checksums.txt
  3. Join this two files and exclude records with same new and old names: join -o "2.2 1.2" sorted_checksums.txt real_checksums.txt | awk '$1 != $2' > rename_pairs.txt
  4. Rename all files: cat rename_pairs.txt | xargs -L 1 echo mv (Remove echo from xargs to actually rename files)

WARNING: this will work only if there is no spaces in filenames. You could use awk 'NF != 2' sorted_checksums.txt real_checksums.txt to check that and if there will be any line printed, then you need to use something else (may be simple perl or python program) for steps 3 and 4.


Read the checksums into an associative array, then walk through the files and rename them as needed. Put the renamed files in a separate directory tree, in case there is overlap between the new names and the old names.

mkdir renamed
typeset -A names
while read -r sum name; do
done <list.md5sum
for file in *; do
  if [[ -f $file ]]; then
    sum=$(md5sum <"$file"); sum=${sum%% *}
    if [[ -n ${names[$sum]} ]]; then
      mv -- "$file" "renamed/${names[$sum]}"

You must log in to answer this question.

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