Відповіді:
Я б використав наступне:
#! /bin/bash
cd DirectoryName
for file in *.csv; do
filename=${file%.*}
file_clean=`echo $filename | tr -cs "[:alnum:]_" _ `
final="$file_clean.csv"
echo "mv \"$file\" \"$final\" "
done
cd ..
Єдиними змінами є:
1) Після рядка у просторі було місце final= "$file_clean.csv". Я його видалив.
2) Замість використання команди команди підстановки я використав tr команду. З tr, -c опція говорить про заміну будь-якого символу ні у наборі. Тому я можу вказати символи, які я хочу зберегти (алфавітно-цифрова і підкреслена, в даному випадку), і всі інші будуть перетворені.
Це має збігатися з деякими спеціальними символами, які важко визначити за допомогою прямого заміщення, наприклад []\{} і ". The -s означає, що буде створено лише одну підкреслення, навіть якщо придушення декількох символів. Таким чином abc((((())))).csv перекладається в abc_.csv замість abc__________.csv
2)без використання зовнішнього виконуваного файлуtr:file_clean=${filename//[^[:alnum:]]/_}. Можна припинити виконання декількох символів, наприклад:shopt -s extglob; file_clean=${filename//+([^[:alnum:]])/_}