Массовое переименование файлов на камкордерах, включая пробелы

Я пытаюсь переименовать пакетные имена с именами, отмеченными на верблюжьих именах, чтобы включить пробелы между соседними верхними и нижними регистрами. Я использую Mac OS, поэтому утилиты, которые я использую, являются BSD-вариантом.

Например:

250 - ErosPhiliaAgape.mp3 => 250 - Eros Philia Agape.mp3 

Я пытаюсь find соответствующие файлы и передать их в mv который запускает sed в подоболочке, используя эту команду:

 find . -name "*[az][AZ]*" -print0 | xargs -0 -I {} mv {} "$(sed -E 's/([az])([AZ])/\1 \2/g')" 

Индивидуально эти команды работают нормально: find вытаскивает правильные файлы, а sed переименовывает их правильно, но когда я их совмещаю с xargs, ничего не происходит.

Что мне нужно изменить, чтобы сделать эту работу?

3 Solutions collect form web for “Массовое переименование файлов на камкордерах, включая пробелы”

Проблема в том, что xargs $(...) в вашей команде оценивается в момент запуска этой команды и не оценивается xargs для каждого файла. Вы могли бы использовать find -exec вместо того, чтобы оценивать команды для каждого файла в sh , а также соответствующим образом заменять цитирование:

 find . -name "*[az][AZ]*" -type f -exec sh -c 'echo mv -v "{}" "$(echo "{}" | sed -E "s/([az])([AZ])/\1 \2/g")"' \; 

Если результат этого выглядит неплохо, отбросьте echo в echo mv . Обратите внимание, что из-за echo | sed echo | sed , это не будет работать с именами файлов со встроенным \n . (Но это было уже существующее ограничение в вашей собственной попытке, поэтому я надеюсь, что это приемлемо.)

Ваша команда sed принимает входные данные из трубы. Он конкурирует с xargs , поэтому каждая из двух команд получит часть данных, записанных find (каждый байт переходит только к одному читателю), и это непредсказуемо, что получает что.

Вам нужно будет связать каждое имя файла с sed , что означает, что вам нужна промежуточная оболочка для настройки канала.

 find . -name "*[az][AZ]*" -print0 | xargs -0 -I {} sh -c 'mv "$0" "$(echo "$0" | sed -E '\''s/([az])([AZ])/\1 \2/g'\'')"' {} 

Вам не нужны xargs , это в основном бесполезно. find может вызвать программу напрямую.

 find . -name "*[az][AZ]*" -exec sh -c 'mv "$0" "$(echo "$0" | sed -E '\''s/([az])([AZ])/\1 \2/g'\'')"' {} \; 

Кроме того, установите любую из реализаций rename Perl, например File::Rename или одну из Unicode::Tussle .

 cpan File::Rename find -depth . -exec rename 's!([az])([AZ])(?!.*/)!$1 $2!g' {} + 

Бит (?!.*/) Запрещает замену от запуска в именах каталогов, если они содержат видеокамеру. Передача -depth для find гарантирует, что если каталог переименован, это произойдет после find как find переместит его.

Если вы предпочитаете использовать GNU Parallel, это решение:

 find . -name "*[az][AZ]*" -type f | parallel mv -v {} '{= s:([az])([AZ])(?!.*/):$1 $2:g =}' 
  • Пропустить флаги для xargs
  • Почему «xargs bash -ic echo» не то же самое, что «xargs echo» или «xargs»?
  • Почему эта труба не заканчивается, когда процесс las умирает (зомби)?
  • Как использовать `yes` с` xargs -p`?
  • найти . . * -тип f -print0 | xargs -0 sudo chmod 664; не работает
  • Расширение оболочки оболочки Ubuntu - путаница с командой sox
  • Переменные ENV по отношению к петлям xargs
  • Получение размера родительских папок при использовании поиска для поиска критериев?
  • Неверное поведение xargs
  • Найдите файлы с определенным форматом файлов, коту, каждый с файлом заголовка, и сохраните результат в исходный файл для каждого такого файла
  • Почему параметр xargs -i устарел?
  • Как выполнить xargs grep для вывода grep с пробелами?
  • Linux и Unix - лучшая ОС в мире.