web-dev-qa-db-ja.com

チェックサムに基づいてファイルの名前を変更する

Md5sumリストと、チェックサムしてmd5sumリストに従って名前を変更したいファイルがたくさんあります。

リストの例:

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

ここで、現在のディレクトリ内のすべてのファイルをチェックサムしたいと思いました。チェックサムが上記のリストと一致する場合は、名前を正しい列に変更します。

どうすればそれができますか?

6
SandPox

私は完全にテストしていません、それは理論的に機能しているだけです。必要に応じて代用:

#! /bin/bash
for II in *
do
    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"
        fi;
    fi;
done;

私が言うように、それをテストしていませんが、それは私の箱で動作するようでした。

2
nonzyro

まず第一に、これが最も深遠な解決策であるとは主張しませんが、これを行う1つの方法があります。

チェックサムとファイル名がfilelist.txtというファイルがあるとすると、次のようなものを使用できます。

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
3

私の考え:

  1. まず、既知のチェックサムを並べ替える必要があります:sort checksums.txt > sorted_checksums.txt
  2. 既存のすべてのファイルのファイルを生成し、それらを並べ替えます:md5sum * | sort > real_checksums.txt
  3. この2つのファイルを結合し、同じ新しい名前と古い名前のレコードを除外します:join -o "2.2 1.2" sorted_checksums.txt real_checksums.txt | awk '$1 != $2' > rename_pairs.txt
  4. すべてのファイルの名前を変更します:cat rename_pairs.txt | xargs -L 1 echo mv(実際にファイルの名前を変更するには、echoからxargsを削除します)

警告:これは、ファイル名にスペースがない場合にのみ機能します。 awk 'NF != 2' sorted_checksums.txt real_checksums.txtを使用して確認できます。印刷される行がある場合は、手順3と4に別のプログラム(単純なPerlまたはpythonプログラムなど)を使用する必要があります。

0
Fedor Dikarev

チェックサムを連想配列に読み込み、ファイルを調べて、必要に応じて名前を変更します。新しい名前と古い名前が重複している場合に備えて、名前を変更したファイルを別のディレクトリツリーに配置します。

#!/bin/bash
mkdir renamed
typeset -A names
while read -r sum name; do
  names[$sum]=$name
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]}"
    fi
  fi
done