Entfernen Sie führende Leerzeichen aus Dateien, Ordnern und deren Unterordnern

Entfernen Sie führende Leerzeichen aus Dateien, Ordnern und deren Unterordnern

Das ist mir eingefallen, aber leider wirkt es sich nicht auf Dateien/Ordner in Unterordnern aus.

find . -exec rename "s/^\s+//" {} \;

Ordnerstruktur:

foo
|-- \ bar
`-- \ foo1
    |-- \ bar1
    `-- \ foo2
        `-- \ bar2

Antwort1

Die Umbenennung muss von unten nach oben erfolgen

Das Problem ist, dass Sie die Verzeichnisse umbenennen müssenvon unten nach oben. Andernfalls versucht der Befehl, Dateien und Verzeichnisse umzubenennen, die sich in bereits verschobenen (umbenannten) Ordnern befinden, und kann sie daher nicht mehr finden.

Hier können python's os.walk()verwendet werden, in Kombination mittopdown=False

In einem kleinen Skript:

#!/usr/bin/env python3
import os
import shutil
import sys

for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        if f.startswith(" "):
            shutil.move(root+"/"+f, root+"/"+f.strip())
    for dr in dirs:
        if dr.startswith(" "):
            shutil.move(root+"/"+dr, root+"/"+dr.strip())

Benutzen

  • Kopieren Sie das Skript in eine leere Datei und speichern Sie es unterno_space.py
  • Führen Sie es mit dem folgenden Befehl aus:

    python3 /path/to/no_space.py /path/to/directory/to/rename
    

Antwort2

Wie in anderen Antworten erwähnt, ist das Hauptproblem, dass ^Anker den Beginn derWegfind, statt dem Anfang des Dateinamens. Es gibt mehrere Möglichkeiten, dies mit und zu umgehen rename: Die sicherste wäre wahrscheinlich, -execdiranstelle von zu verwenden -exec, sodass alle Pfadkomponenten auf reduziert werden ./, und dann das Muster zu ersetzen.\./\s+

Auch wenn Sie Verzeichnisse umbenennenggf. inklusive Vorgänger anderer umzubenennender Dateien/Verzeichnisse, dann sollten Sie eine Tiefensuche durchführen.

Etwas zusammensetzen,

find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +

oder (funktional gleichwertig, aber etwas einfacher zu erkennen) Verwendung eines „Lookbehind“ mit der Länge Null als Pfadtrennzeichen

$ find . -depth -name ' *' -execdir rename -vn -- 's#(?<=\./)\s+##' {} +
./ bar2 renamed as ./bar2
./ foo2 renamed as ./foo2
./ bar1 renamed as ./bar1
./ foo1 renamed as ./foo1
./ bar renamed as ./bar

[HINWEIS: Entfernen Sie es, -nsobald Sie sicher sind, dass es das gewünschte Ergebnis liefert.]

Antwort3

Ich denke, das Problem liegt im Ausgabeformat von find, das den vollständigen Pfad enthält. Für bar2 haben Sie also

./ foo1/ foo2 /bar2

dass die Umbenennung nicht richtig verstanden wird.

Eine Lösung besteht darin, mithilfe eines Skripts jeden Ordner rekursiv wie folgt zu bearbeiten:

#!/bin/bash
# if argument given consider it is the directory to parse
if [ -n "$1" ]; then
    cd "$1"
fi
# rename all files in current folder
find . -maxdepth 1 -printf '%f\0'  | xargs -0r -n 1 rename -nono 's/^\s+//'
# No, repeat for all subfolders with current script (we are in the subfolder)
find . -maxdepth 1 -type d -not -name '.' -print0 | xargs -0r -n 1 "$(readlink -f $0)"

verwandte Informationen