Hapus karakter khusus dan ganti ruang dengan _ dari file dan direktori Secara rekursif di Bash

1

Saya memiliki skrip yang memberi saya beberapa masalah, saya tahu bahwa saya harus melakukannya kembali secara rekursif tetapi mengalami masalah. Skrip harus mengganti nama semua file dan folder dalam folder yang diberikan dengan menghapus karakter khusus seperti $ -,) (! Dan mengganti "" dengan "_"

Inilah bagian yang harus saya lakukan kembali:

# 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
Erick
sumber
Di mana Anda mengalami masalah dengan skrip ini? Apakah Anda mendapatkan pesan kesalahan, apakah ia melakukan sesuatu yang berbeda dari yang diharapkan?
nohillside
Pesan kesalahan yang saya dapatkan pada akhirnya adalah bahwa tidak ada file atau direktori tersebut. Skrip ini juga tidak akan menghapus!, $ -) (
Erick
Nah, satu masalah dengan skrip adalah keduanya find perintah akan selalu melintasi seluruh pohon direktori (ganti fungsi di dalamnya dengan pernyataan gema untuk melihat apa yang terjadi).
nohillside

Jawaban:

1

Belum dicoba

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

Jika terlihat OK, hapus "echo"

Kuncinya di sini adalah opsi "-depth" untuk menemukan. Ini akan memancarkan "./sub dir / nama file" sebelum "./sub dir". Kalau tidak, jika "./sub dir" diganti nama menjadi "./subdir", maka Anda akan mendapatkan kesalahan 'file not found' ketika loop sementara sampai ke "./sub dir / nama file". Juga, itu berarti Anda tidak memerlukan logika berbeda untuk direktori.

Opsi "-print0" untuk menemukan dan kesibukan di sekitar perintah baca adalah untuk memastikan nama file dengan spasi ditangani dengan benar.

glenn jackman
sumber
Ini adalah langkah yang baik tetapi terlalu jauh. Ini akan menghapus "." sebelum ekstensi file yang tidak bagus. Saya juga ingin menyimpan garis bawah dan ruang diganti dengan garis bawah. Kedua saya memberi nama folder dalam perintah, yaitu Folder A, tetapi skrip memukul semua folder di direktori yang berisi Folder A.
Erick