Вы можете использовать dirname/basename, чтобы разделить вашу переменную $ f на $ fdir и $ fbase, и отредактировать только $ fbase, и остаться в стороне от dir, но на самом деле это выглядит не намного лучше, чем ваше решение для cd . .. (не думаю, что для удаления части косой черты в $ fbase требуется расширение параметра, поэтому становится немного меньше. Может даже быть в состоянии использовать замену шаблона вместо sed , но sed уже работает достаточно хорошо)
for f in "$@"
do
fbase=$(basename "$f")
fdir=$(dirname "$f")
mv "${fdir}${fbase}" "${fdir}$(echo "${fbase}" | sed -e 's/[^A-Za-z0-9._-]/_/g')"
done
Но мне также интересно, может ли ваш for f in "$@" столкнуться с недопустимыми именами файлов, не отделяя $ f должным образом без каких-либо возни с IFS, но держу пари, что Automator позаботится об этом.
Другой вариант может состоять в том, чтобы запустить find а затем использовать его -exec или -execdir или даже xargs для поиска и переименования файлов, и есть программа rename которая может делать такие вещи, как «перевод заглавных букв в нижние, вы должны использовать« rename 'y/A-Z/a-z/' * но они могут не работать с Automator.
На самом деле, я попытаюсь провести быстрый тест, чтобы увидеть, что делает rename одиночку с именем файла с полными путями ... неожиданным "нет такого файла" при отображении правильного полного пути:
$ rename 'y/A-Z/a-z/' "/home/me/Downloads/NEWFILE-Z1.txt"
Can't rename /home/me/Downloads/NEWFILE-Z1.txt /home/me/downloads/newfile-z1.txt: No such file or directory
Не похоже на большое улучшение по сравнению с mv, but переименование может сократить количество вложенных оболочек, труб и эха ...
$ rename -v 's/[^A-Za-z0-9._-]/_/g' New\ space\ file.txt
New space file.txt renamed as New_space_file.txt
Я добавлю его в скрипт, меньше, но он вернется к cd , и " цитирование работает» вокруг вызова subshell:
for f in "$@"
do
cd $(dirname "$f")
rename 's/[^A-Za-z0-9._-]/_/g' "$(basename "$f")"
done