Избегайте замены пробелов при переименовании файлов
Я пытаюсь переименовать файлы следующим образом:
for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done
Но sed
команда заменяет все пробелы _
,
Как я могу редактировать sed
команда, чтобы сделать это внутри пробелов вместе с указанными символами? Я пытался использовать \s
Но это не работает...
РЕДАКТИРОВАТЬ:
Например: файл trip: hill
, следует переименовать: trip_ hill
, но команда выше делает это trip__hill
,
2 ответа
Не анализируйте имена файлов с sed
! Выход из echo "$file"
может быть не надежным.
использование rename
, 17.10 сначала нужно установить
sudo apt install rename
Затем:
rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *
Заметки
- Удалить
-n
после тестирования, чтобы фактически переименовать файлы --
конец опций, если любой файл начинается с-
[^-A-Za-z0-9_ .]
символы мы не хотим заменять - ставим-
первый или последний, поэтому он не может указывать диапазон (он рассматривается буквально в этих позициях).- Пробелы могут быть включены в класс
.
трактуется буквально (в других контекстах регулярных выражений он обозначает любой символ и должен быть экранирован).
Это также работает в sed
:
$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill
Если я добавлю пробел в конец вашей версии, я получу сообщение об ошибке:
$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end
Но с -
в конце это работает:
$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill
Так что, возможно, положение дефиса вызвало вашу проблему, когда вы добавили пробел. Но совет не разбирать имена файлов стоит!
Вы также можете просто использовать оболочку, расширение параметра Bash может сделать замену:
for f in ./* ; do
mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done
Двойная косая черта говорит ему заменить все совпадения, кроме этого, синтаксис прост.