Ich bin sehr neu in Linux / Befehlszeile und muss die Namen von 10K + -Dateien (eindeutige Namen) verschlüsseln, damit sie mit dem MD5-verschlüsselten Namen in der mySQL-Datenbank übereinstimmen.
Ich habe gesehen, wie Sie ein Verzeichnis von Dateien umbenennen und den Hash einer Datei abrufen können ( mdsum? ), Aber ich bin nicht sicher, wie ich den Hash des Dateinamens abrufen und diese Datei dann in den generierten Hash umbenennen kann die Erweiterung dh
mynicepicture.jpg > fba8255e8e9ce687522455f3e1561e53.jpg
Es scheint, als sollte es eine einfache Umbenennung oder mv
Zeile sein, aber ich kann mich nicht darum kümmern.
Vielen Dank für Ihre Erkenntnisse
PS Ich habe die Verwendung von Perl-Funktionen in einigen Beispielen gesehen, die genau dem entsprechen, wonach ich suche, habe aber keine Ahnung, wo / wie diese verwendet werden sollen.
quelle
fba8255e8e9ce687522455f3e1561e53
Ist der MD5-Hash fürmynicepicture
, bedeutet das, dass die Erweiterung vor dem Hashing entfernt werden sollte?md5sum <<<"file name"
diefile name
Datei vorhanden machen oder nicht, weil sie als Zeichenfolge betrachtet wird, außer sie mit dem Namen der vorhandenen Datei zu füttern.Antworten:
Sie haben nicht gesagt, welche Shell Sie verwenden möchten, also gehe ich nur von Bash aus - die Antwort muss angepasst werden, um mit anderen Shells zu arbeiten.
Skriptversion:
Diese einfache
for
Schleife nimmt jede Datei im aktuellen Verzeichnis, berechnet die md5-Summe ihres Namens und gibt sie aus. Verwenden Sie diese Option, um die Funktionalität zu überprüfen. Wenn Sie mit dem Umbenennen beginnen möchten, ersetzen Sie die zweiteecho
durchmv
.Erklärungen
echo -n "$i" | md5sum
- Berechnen Sie die md5-Summe des vollständigen Dateinamens einschließlich der Dateierweiterung ( Piping ), um die Erweiterungsänderungecho -n "$i"
auf eine der folgenden zu reduzieren:sum=$(…)
- Ausführung ausführen…
und speichern in$sum
( Befehlsersetzung )${sum%% *}
- alles bis zum ersten Leerzeichen ausgeben ( Parametersubstitution ), das gleiche wie eines der folgenden:${i##*.}
- alles nach dem letzten Punkt ausgeben (Parametersubstitution), wie einer der folgenden:Wenn Sie Dateien müssen in verschiedenen Ordnern rekursiv umbenennen, verwenden Sie
find
die-exec
Option.quelle
Dieses
bash
Skript verwendet dasmd5sum
Dienstprogramm von GNU coreutils, um den MD5-Hash aus dem Basisnamen (ohne Erweiterung) eines bestimmten Pfadnamens zu berechnen. Die Hilfsfunktionmd5name
führt die eigentliche Berechnung durch und gibt den neuen Namen mit vollständigem Pfad und Erweiterung aus.Die
md5name
Funktion verwendetawk
, um den neuen Namen aus den Teilen des angegebenen Pfadnamens und dem Ergebnis von zusammenzusetzenmd5sum
.Beispiele für die selbst verwendete Funktion:
... wo
c9e89fa443d16da4b96ea858881320c9
ist der MD5 - Hash der Zeichenfolgefile name here
.Entfernen Sie das
echo
aus dem Skript oben, um die Dateien tatsächlich umzubenennen. Möglicherweise möchten Sie die Ausgabe des ursprünglichen Skripts in einer Datei speichern (mit der vorhandenenecho
), wenn Sie irgendwann die Dateinamen auf ihren Originalen wiederherstellen müssen.Beachten Sie, dass durch zweimaliges Ausführen einer Reihe von Dateien der MD5-Hash von MD5-Hashes berechnet wird und der ursprüngliche Dateiname dann nicht mehr wiederhergestellt werden kann, es sei denn, Sie machen nach jeder Ausführung des Skripts sorgfältig Notizen darüber, welche Dateien wie heißen.
quelle
awk
Information könnte der Teil durch ersetzt werden.while read sum dummy ; do printf "%s/%s.%s\n' $dir $sum $ext ; done ;
Sie benötigen dasdummy
, um das '-' zu erfassen.awk
mich und es hat eine Weilebash
gedauert, bis ich Dienstprogramme verwendet habe, anstattsystem()
inawk
Mit
perl
'srename
:(entfernen,
-n
wenn glücklich).quelle
Für einen
AWK
Ansatz:Moderne
find
Befehle erfordern kein Verzeichnis für die Eingabe.
, daher kann das [Verzeichnis] leer bleiben. Das-type f
einzige findet Dateien, was praktisch ist, damd5sum
es keine Verzeichnisse mag und das Ändern des Verzeichnisnamens während der Ausführung keine gute Idee wäre. Verwenden Sie,-iname pattern
wenn Sie nur einige Dateien verwenden möchten, zum Beispiel-iname \*.dat
, wenn Fall wichtig ist, verwenden Sie-name
statt-iname
.Die
match(...); sub(...)
Teile extrahieren Teile des Dateinamens und ersetzen sie in der Eingabezeichenfolge. Beachten Sie, dass"^"
und"$"
[pre / ap] anhängig sind, um zu verhindern, dass eine Zeichenfolge ersetzt wird, die den Pfad / die Erweiterung wiederholen kann.Ersetzen
print(com)
durchsystem(com)
, um die Umbenennung tatsächlich durchzuführen.Wenn Sie
md5sum
die tatsächliche Datei als Namen verwenden möchten, können Sie die Tatsache, dassmd5sum
die Summe und der Eingabedateiname ausgegeben werden, verwenden, um Folgendes zu tun:Das
while read sum file
dauert zwei Argumente, die Ergebnisse desmd5sum
Befehls und assignsum
undfile
Variablen mit ihnen. Da dassum
keine Leerzeichen enthaltenread
sollte , sollte das gut funktionieren.Natürlich
[echo]
sollte das entfernt werden, wenn es tatsächlich ausgeführt wird, aber es ist immer eine gute Idee, wenn Sie Skriptänderungen testen, um die Suche vor dem Ausführen zu testen.Dies alles setzt voraus, dass Sie laufen
bash
. Dies kann auch als eine längere Zeile eingegeben werden:quelle
Diesen Ansatz verwende ich oft.
Der Befehl "ls" erzeugt einen Strom von Textzeilen. Der Befehl "sed" transformiert jede Zeile mit Mustervergleichsregeln. Der Befehl "sed" gibt einen Befehl "mv" aus, der dann zur Ausführung durch eine Shell "sh" geleitet wird. Die Parameter des Befehls "mv" entsprechen "mv oldfilename newfilename", wodurch die Datei umbenannt wird. Ich konstruiere den neuen Dateinamen mit einem sed-Befehl, der den Teil vor dem letzten Punkt übernimmt, ihn in die Eingabe des Befehls "md5sum" überträgt und dann nur den Hash aus seiner Ausgabe entnimmt.
Gehen Sie durch meinen Prozess und listen Sie zuerst die Dateien auf ('head -n 3', um nur die ersten 3 Zeilen zu sehen):
Denken Sie dann an die Transformation mit sed (noch keine generierten Befehle durch eine Shell leiten)
Es gibt drei Übereinstimmungsmuster:
Ich möchte sed verwenden, um einen Eingabedateinamen durch "mv Dateiname NEWfilename" zu ersetzen, aber da ich Befehle durch eine Shell leite, kann ich Befehle generieren, die die md5sum erhalten, wie folgt
um nur den Hash zu bekommen
In einer Unix-Shell können wir Backtick-Operatoren (`some_command`) verwenden, um beispielsweise einen Unterbefehl auszuführen
Zurück zum Befehl mv möchte ich, dass sed "mv here there" erzeugt, wobei "there" durch einen Backtick-Befehl ersetzt wird, um die md5sum zu erhalten. Die Saite innerhalb der sed replace-Saite beginnt so
Es wird jedoch eindeutig für jeden Dateinamen der gleiche Hash erstellt, da der Befehl backticked ausgeführt wird, bevor sed die Zeichenfolge sieht. Um zu verhindern, dass die Shell den Befehl backtick ausführt, damit sed die Backticks ausgibt, müssen wir Schrägstriche (auch dem Pipe-Zeichen) voranstellen, also noch einmal:
Für die Ausgabe müssen auch Dateinamen bei Leerzeichen angegeben werden
Probieren wir es also aus, indem wir es durch eine Shell leiten:
Hat es funktioniert ? ich vermute:
Hier ist ein Ansatz zur Gegenprüfung. Verwenden Sie die Option "-s" "-i", um den i-Knoten des Unix-Dateisystems auszugeben (der sich mit "mv" nicht ändert):
Oder verwenden Sie den Befehl "Einfügen" (Paket 'coreutils').
quelle
Ich mag diese einzeilige Antwort, aber sie bricht ab, weil sie den Dateinamen analysiert. Ich habe es auch ein bisschen mit Sha-Hashes aufgepeppt.
Ich denke, es zieht auch die Dateien heraus und platziert sie an der Basis, an der der Befehl eingegeben wurde.
Vielen Dank.
quelle