Избегайте замены пробелов при переименовании файлов


10

Я пытаюсь переименовать файлы следующим образом:

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.


Я перемещаю некоторые файлы из Linux в Mac. Но по какой-то причине система Mac не может прочитать все имена файлов, поэтому я пытаюсь переименовать мои файлы. Добавление пробела к команде выше не работает. И вы правы: я хочу заменить все символы на '_', кроме указанных. И я не знаю, как включить космический символ.

Обратите внимание, что я пытаюсь заменить все символы на «_», кроме указанных. Для переименованных файлов нет определенного шаблона, поэтому я не могу использовать эту команду perl.

Ответы:


11

Не анализируйте имена файлов с помощью 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

Так что, возможно, положение дефиса вызвало вашу проблему, когда вы добавили пробел. Но совет не разбирать имена файлов стоит!


Эта команда работает спасибо. Вы также четко определили ошибки в команде, которую я использовал.

2
Еще раз спасибо. Обратите внимание, что нет необходимости использовать косую черту '\' в случае использования sed. Потому что это добавляет «\» в список игнорируемых символов.

2
@latach Это обратный слеш, но ты абсолютно прав. После тестирования и копания я обнаружил, что .это буквально в классе персонажей. TIL!
Занна

2

Вы также можете просто использовать оболочку, расширение параметра Bash может сделать замену:

for f in ./* ; do
    mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done

Двойная косая черта говорит ему заменить все совпадения, кроме этого, синтаксис прост.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.