Entfernen Sie bestimmte Zeichen aus Dateinamen

Entfernen Sie bestimmte Zeichen aus Dateinamen

Ich verstehe davon nur wenig. Der folgende Befehl entfernt die Leerzeichen aus allen Dateinamen.

find . -type f -name "* *.*" -exec bash -c 'mv "$0" "${0// /}"' {} \;

Ich möchte, dass auch Kommas, Punkte und Klammern (   ,  ,,  .,  ( und  ) ) entfernt werden, weiß aber nicht, wo im Befehl ich die zu entfernenden Zeichen platzieren soll.

Antwort1

Die kurze Antwort lautet: Der Befehl zum Entfernen von Leerzeichen, Kommas, Punkten und Klammern aus einem Dateinamen (in  $0) lautet

mv "$0" "${0//[ ,.()]/}"

Aber benutze das nicht …

Längere Antwort:

  • Ihr findBefehl lautet -name "* *.*". Dadurch werden Dateien ausgewählt, deren Namen mindestens ein Leerzeichen enthalten gefolgt von mindestens einem Punkt.  Es ist sinnvoll, nicht zu versuchen, Dateien zu verarbeiten, deren Namen keine Leerzeichen enthalten, da ohne Leerzeichen nichts entfernt werden kann. Aber ich weiß nicht, warum dieser Befehl auf einen Punkt prüft. Er wird in umbenannt fat cat.txt, fatcat.txtlässt aber hot dogund frank.fur terunberührt.

    Da Sie Dateien mit Punkten im Namen umbenennen möchten (um die Punkte zu entfernen), sollten Sie Ihren -nameTest in  ändern -name "*[ ,.()]*".

  • Wenn Sie mit Dateinamen arbeiten, die im Voraus nicht bekannt sind, setzen Sie am besten  --vor den ersten Dateinamen. Man könnte argumentieren, dass dies nicht unbedingt erforderlich ist, wenn Sie dies tun find . … -exec …, aber es ist eine gute Angewohnheit, die Sie sich aneignen sollten.

  • Wenn Sie Dateien mit den Namen fat cat.txtund haben f a t c a t.txt, werden beide in umbenannt fatcat.txt, und die zweite Datei überschreibt die erste. -nWenn Sie die Option (no-clobber) an übergeben mv , wird dies verhindert. Aber Vorsicht: Es bleiben Dateien mit Leerzeichen (usw.) in ihren Namen übrig, und Sie werden möglicherweise nicht einmal darüber informiert, dass ein Problem aufgetreten ist!

  • Ihr aktueller Befehl ruft bashfür jede Datei einen neuen Prozess auf. Dies kann dazu führen, dass es länger dauert als nötig. Es ist besser, den Prozess basheinmal und dann mvmehrere Male aufzurufen. Wenn wir also alle oben genannten Punkte berücksichtigen, haben wir

    find . -type f -name "*[ ,.()]*" -exec bash -c 'mv -n -- "$1" "${1//[ ,.()/}"' sh {} +
    

    Aber warten Sie! Wir sind noch nicht fertig! Verwenden Sie das oben genannte nicht.

  • Wenn findein Befehl (mit  -exec) ausgeführt wird, übergibt er dem Befehl einen Pfadnamen zur Datei. Wenn Sie fat cat.txtin Ihrem aktuellen Verzeichnis eine Datei mit dem Namen haben, findwird diese an den Bash-Befehl übergeben ./fat cat.txt. Der obige Befehl versucht, fat cat.txt( ./fat cat.txt) in  umzubenennen /fatcattxt. Wenn Sie als Root (d. h. ) arbeiten  sudo, werden Ihre Dateien dadurch in das Stammverzeichnis verschoben, was ein großes Durcheinander verursacht. (Lektion: Führen Sie keine Befehle unter aus, sudoes sei denn, Sie sind sicher, dass Sie sie benötigen.) Wenn Sie nicht als Root arbeiten, ist die „gute Nachricht“, dass der Befehl nichts bewirkt.

    Wenn wir nun alles zusammenfassen, erhalten wir

    find . -type f -name "*[ ,.()]*" -exec bash -c 'for f do dir="$(dirname "$f")"; base="$(basename "$f")"; echo mv -n -- "$f" "$dir/${base//[ ,.()]}"; done' sh {} +
    

    Beachten Sie, dass ich echooben einen Befehl eingefügt habe, als „Erst schauen, dann handeln“-Maßnahme. Wenn Sie den obigen Befehl ausführen, werden Ihnen alle mverforderlichen Befehle angezeigt. Wenn alles in Ordnung zu sein scheint, führen Sie den Befehl erneut aus, ohne das „ echo“ zu verwenden.


Übrigens schlägt der Befehl, den Sie in der Frage zeigen, fehl, wenn Dateien mit einem .in ihrem Namen befinden sich in einem Verzeichnis, dessen Name ein Leerzeichen enthält.

verwandte Informationen