Usuń znaki specjalne i zamień spację na _ z plików i katalogów Rekurencyjnie w Bash


1

Mam skrypt, który sprawia mi pewne problemy, wiem, że muszę to zrobić rekurencyjnie, ale mam pewne problemy. Skrypt powinien zmienić nazwę wszystkich plików i folderów w danym folderze, usuwając znaki specjalne, takie jak $ -,) (! I zamieniając „” na „_”

Oto fragment, który muszę wykonać ponownie:

# Rename directories
find "$ORIG_DIR" -name "*" -type d| while read dname
do
    NEW_DIR=`echo "$dname" |sed -E 's/^[ \t]*//g; s/[ \t]*$//g; s/\./_/g; s/\,/_/g; s/ /_/g'`

        # Rename files
        find "$ORIG_DIR" -name "*" -type f | while read fname
        do
            NEW_FNAME=`echo "$fname" |sed -E 's/^[ \t]*//g; s/[ \t]*$//g; s/\./_/g; s/(.*)_/\1\./; s/\,/_/g; s/ /_/g'`
            if [ -e $NEW_FNAME ]
            then
                echo "$NEW_FNAME already exists. Not replacing $fname"
            else
                echo "Replacing $fname with $NEW_FNAME"
                mv "$fname" $NEW_FNAME
            fi
        done

    if [ -e $NEW_DIR ]
    then
        echo "$NEW_DIR already exists. Not replacing $dname"
    else
        echo "Replacing $dname with $NEW_DIR"
        mv "$dname" $NEW_DIR
    fi
done

END

Gdzie masz problemy z tym skryptem? Czy otrzymujesz komunikaty o błędach, czy robi coś innego niż oczekiwano?
nohillside

Komunikat o błędzie, który pojawia się na końcu, jest taki, że nie ma takiego pliku ani katalogu. Ten skrypt również nie usuwa!, $ -) (
Erick

Cóż, jednym ze problemów ze skryptem jest to, że obie findkomendy zawsze będą przechodzić przez całe drzewo katalogów (zamień funkcjonalność wewnątrz na instrukcje echo, aby zobaczyć, co się dzieje).
nohillside

Odpowiedzi:


1

Niesprawdzone

find . -depth -print0 |
while IFS= read -d '' -r file; do
    dir=$(dirname "$file")
    base=$(basename "$file") 
    base=${base//[[:space:]]/_}         # change whitespace to underscores
    base=${base//[^[:alnum:]_.]/}       # delete any chars not alphanumeric _ .
    newname="$dir/$base"
    if [[ -e $newname ]]; then
        echo "'$newname' exists, not renaming '$file'"
    else
        echo mv "$file" "$newname"
    fi
done

Jeśli wygląda OK, usuń „echo”

Kluczem jest tutaj opcja „-depth” do znalezienia. Będzie emitował „./sub dir / file name” przed „./sub dir”. W przeciwnym razie, jeśli nazwa „./sub dir” zostanie zmieniona na „./subdir”, pojawi się błąd „nie znaleziono pliku”, gdy pętla while przejdzie do „./sub dir / file name”. Oznacza to również, że nie potrzebujesz innej logiki dla katalogów.

Opcja „-print0” znajdowania i zajętość wokół polecenia read mają na celu zapewnienie poprawnej obsługi nazw plików ze spacjami.


To dobry krok, ale idzie za daleko. Spowoduje to usunięcie „.” przed rozszerzeniem pliku, które nie jest dobre. Chcę też zachować wszelkie znaki podkreślenia i zastąpić spacje znakami podkreślenia. Po drugie, nazwałem folder w poleceniu, tj. Folder A, ale skrypt uderzył we wszystkie foldery w katalogu zawierającym Folder A.
Erick
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.