Ich begann mit dem Schreiben eines einfachen Bash-Shell-Skripts, um doppelte Dateien in einem bestimmten Verzeichnis zu finden. Dabei verwendete ich SHA1, um Übereinstimmungen zu erkennen. Alles funktionierte, bis ich auf Dateinamen mit Leerzeichen stieß. Die Erkennung funktioniert immer noch, aber in der Ausgabe werden die Leerzeichen in Zeilenumbrüche umgewandelt.
Das Skript...
#!/bin/bash
export TARGET=$1
find $TARGET -type f -exec openssl sha1 \{\} \; > ./dupes.txt
COUNT=-1
for EVALUATION in `cat ./dupes.txt | sed 's/SHA1(\(.*\))\= \(.*\)$/\2 \1/' | awk '{print $1}' | sort | uniq -c | sort -nr`
do
if [[ $COUNT == -1 ]]
then
COUNT=$EVALUATION
else
HASH=$EVALUATION
if [[ $COUNT == 1 ]]
then
break
fi
echo "--- duplicate set ---"
for FILE in `grep $HASH ./dupes.txt | awk -F"[()]+" '{print $2}'`
do
echo "$FILE"
done
echo "---------------------"
COUNT=-1
fi
done
Führen Sie das Skript wie folgt aus:
./dupes.sh /home/dacracot/testDupes
Es wird eine Datei dupes.txt erstellt, die ungefähr so aussieht ...
SHA1(/home/dacracot/testDupes/lP3wj.jpg)= 324d91f412745481ed38aa184e5a56bfc3bf43b5
SHA1(/home/dacracot/testDupes/1673.gif)= 9c4029ec2e310f202b413d685209373d234e5465
SHA1(/home/dacracot/testDupes/.DS_Store)= b0ae6631a1412863f958da64091f4050005bf8d6
SHA1(/home/dacracot/testDupes/tae 2.svg)= 3ddc4fd6ae505bd01f370d0a018ef1f84b4d8011
SHA1(/home/dacracot/testDupes/tae.graffle)= 77f1ad6d695d944abacfe3a7f196be77125b6ef6
SHA1(/home/dacracot/testDupes/tae.svg)= 3ddc4fd6ae505bd01f370d0a018ef1f84b4d8011
SHA1(/home/dacracot/testDupes/22402_graph.jpg)= 24e5a25c8abf322d424dd5ce2e5b77381cd001c4
SHA1(/home/dacracot/testDupes/forwardcont.jpg)= 981e75060ae8e3aad2fe741b944d97219c8ccbe5
SHA1(/home/dacracot/testDupes/tae.svg.gz)= 922af5a5adbf7a4e7fd234aac7bcee2986133c4d
SHA1(/home/dacracot/testDupes/Alt2012.pdf)= 97d1fd997df9eb310b30a371c53883f5227cf10a
SHA1(/home/dacracot/testDupes/vcBZ8.jpg)= 7553c19fcb6aa159aada2e38066b5ba84465ee57
SHA1(/home/dacracot/testDupes/derm.graffle)= 0e1c4032f5f1fadc3a1643b2b77f816011c2d67f
SHA1(/home/dacracot/testDupes/WA.png)= 0e2e77624c3a76da4816f116665a041f6bdced2d
SHA1(/home/dacracot/testDupes/DRAW.GIF)= 6a8e4a2bf413e84140a0edeb40b475a5d3e4c255
SHA1(/home/dacracot/testDupes/crazyTalk.gif)= 1d938bbcb8cf09f30492df4504a50348cef7ea9d
Und schließlich sieht die Ausgabe so aus ...
--- duplicate set ---
/home/dacracot/testDupes/tae
2.svg
/home/dacracot/testDupes/tae.svg
---------------------
Aber wie Sie der ersten Datei entnehmen können, sollte die Ausgabe wie folgt aussehen:
--- duplicate set ---
/home/dacracot/testDupes/tae 2.svg
/home/dacracot/testDupes/tae.svg
---------------------
Was bedeutet die Änderung des Leerzeichens in einen Zeilenvorschub?
Antwort1
Darf ich einige Änderungen an Ihrem Skript vornehmen, um es zu vereinfachen und auch Ihr Problem zu beheben?
Ich sehe, Sie verwenden OpenSSL, um den SHA1-Hash zu berechnen, analysieren dann einige unnötige Ausgaben und fahren mit dem Sortieren und Durchlaufen der Hashliste fort. Sie geben in Ihrem Beitrag kein OS-Tag an, aber Ihre Verwendung von /bin/bash
deutet auf Linux hin. Warum also nicht stattdessen verwenden sha1sum
? Dadurch wird eine einfachere Ausgabe erzeugt, die für Ihr Skript leichter zu verarbeiten ist. (Leser, die BSD verwenden, können verwenden, sha1 -r
um eine gleichwertige Ausgabe zu erhalten.)
#!/bin/bash
find "$1" -type f -exec sha1sum \{\} \; > dupes.txt
awk '{print $1}' < dupes.txt |
sort | uniq -c | sort -nr |
while read COUNT HASH; do
if [[ $COUNT == 1 ]]; then
break
else
echo "--- duplicate set ---"
grep "^$HASH " dupes.txt | sed -e "s/[^ ]* //"
echo "---------------------"
fi
done
Es könnten noch weitere Optimierungen vorgenommen werden, wie etwa die Verwendung find
der Option von -print0
und xargs
, aber hoffentlich helfen Ihnen die oben aufgeführten Überarbeitungen beim Einstieg.