私はmd5sumリストと多くのファイルを持っており、チェックサムを計算してからmd5sumリストに基づいて名前を変更したいと思います。
リストの例:
d4cd401ade018617629b39efed7b7be4 foo.bar
8fdb07ca55c164e0d5a69eff49fe800e bar.foo
8b167d01009f066aaf2d6c1ba336d842 foobar
現在のディレクトリのすべてのファイルをチェックし、チェックサムが上記のリストと一致する場合は、名前を正しい列に変更したいと思います。
どうすればいいですか?
答え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
答え2
まだ完全にテストされておらず、理論的にのみ動作します。必要に応じて交換してください。
#! /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;
私が言ったように、まだテストしていませんが、私のボックスで動作しているようです。
答え3
私の考え:
- まず、既知のチェックサムをソートする必要があります。
sort checksums.txt > sorted_checksums.txt
- すべての既存ファイルのファイルを作成してソートします。
md5sum * | sort > real_checksums.txt
- 両方のファイルをリンクし、古い名前と新しい名前が同じレコードを除外します。
join -o "2.2 1.2" sorted_checksums.txt real_checksums.txt | awk '$1 != $2' > rename_pairs.txt
- すべてのファイル名を変更する:(
cat rename_pairs.txt | xargs -L 1 echo mv
実際にファイル名を変更するにはここから削除)echo
xargs
警告:ファイル名にスペースが含まれていない場合にのみ機能します。これを確認するために使用できますawk 'NF != 2' sorted_checksums.txt real_checksums.txt
。行が印刷されたら、他の方法(単純perl
またはpython
手順)を使用して手順3と4を実行する必要があります。
答え4
チェックサムを連想配列に読み込み、ファイルを繰り返し、必要に応じて名前を変更します。新しい名前と古い名前が重複しないように、名前が変更されたファイルを別のディレクトリツリーに配置します。
#!/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