Почему я не могу применить -R с rm на macOS Sequoia (15.3.1), чтобы удалить файлы в подпапках с использованием подстановочного знака?

Вопрос или проблема

Я использую macOS Sequoia (15.3.1) и у меня возникают трудности с удалением файлов в папке и её подпапках с помощью rm -R + масок, таких как *1.XXX.

В моей музыкальной библиотеке на Mac несколько дублирующихся файлов (*.mp3, *.m4p), и я пытаюсь их удалить, избегая ручного перехода в каждую папку. Поскольку дублирующиеся файлы имеют имена, заканчивающиеся на 1 или 2, *1.mp3 работает нормально.

Я заметил, что простое ls -r *.* или *.mp3 также не дает никаких результатов (нет найденных совпадений, хотя я знаю, что там есть файлы).

Но если я перехожу в конкретную папку и набираю rm *1.mp3, это работает.

* — это подстановочный знак, который разворачивается в оболочке, а не интерпретируется rm. Написание *1.mp3 означает “все файлы, заканчивающиеся на 1.mp3 в директории”. Если в родительской директории, из которой вы запускаете rm, нет таких файлов, это развернется в пустоту.

Вы можете получить желаемое поведение с помощью команды find:

find . -type f -name "*1.mp3" -exec rm -i {} \;

Замечания:

  1. Обратите внимание на кавычки (") вокруг шаблона файла – это сделано для предотвращения интерпретации * оболочкой и чтобы find обрабатывал его.
  2. -i — это мера предосторожности, чтобы предотвратить удаление файлов, которые вы не собирались удалять. Если вы запускаете эту команду и удовлетворены тем, что она находит правильные файлы, вы можете удалить -i, чтобы не нужно было вручную подтверждать каждое удаление.

Ответ или решение

Проблема, с которой вы столкнулись на macOS Sequoia (15.3.1), связана с использованием команды rm -R в сочетании с подстановочными символами (wildcards), такими как *1.XXX, для удаления файлов в каталоге и его подкаталогах. Давайте разберем, почему это происходит.

Теория

  1. Общее понимание командной строки и подстановочных символов: В Unix-подобных системах, таких как macOS, оболочка (например, Bash) интерпретирует подстановочные символы (wildcards) до передачи команды для выполнения. Это означает, что когда вы вводите rm *1.mp3, оболочка сначала пытается расширить *1.mp3 в текущем каталоге, подставляя все существующие файловые имена, которые соответствуют этому шаблону. Если в текущем каталоге нет таких файлов, то *1.mp3 расширяется в пустую строку, и rm фактически ничего не удаляет.

  2. Поведение команды rm -R: Опция -R используется для рекурсивного удаления каталогов и их содержимого. Однако она не влияет на интерпретацию подстановочных символов оболочкой. Это значит, что если *1.mp3 не находит соответствий в текущем каталоге, rm -R также не сможет удалить файлы в подкаталогах просто потому, что они не были найдены на этапе расширения подстановок.

Пример

Предположим, что у вас есть директория MusicLibrary, содержащая несколько подкаталогов с файлами, названия которых заканчиваются на 1.mp3. Если вы находитесь в корне MusicLibrary и используете команду ls -r *1.mp3, она не будет ничего выводить, если в корневом каталоге нет файлов, соответствующих шаблону *1.mp3.

Однако, если переместиться в подкаталог и выполнить rm *1.mp3, система удалит файлы, поскольку оболочка успешно расширяет *1.mp3 в набор конкретных файлов в этом каталоге.

Применение

Для решения вашей задачи на macOS Sequoia (15.3.1) можно использовать команду find, которая обходит все подкаталоги без необходимости предварительного расширения подстановочных символов оболочкой:

find . -type f -name "*1.mp3" -exec rm -i {} \;

Работа команды пошагово:

  • find . — запускает поиск в текущем каталоге и во всех его подкаталогах.
  • -type f — ограничивает поиск только файлами (исключает директории).
  • -name "*1.mp3" — определяет шаблон для поиска. В данном случае find ищет файлы, имена которых заканчиваются на 1.mp3. Подстановочный символ * заключен в кавычки, чтобы оболочка не интерпретировала его.
  • -exec rm -i {} \; — выполняет команду rm -i для каждого найденного файла. Опция -i предназначена для запроса подтверждения перед удалением каждого файла, что является мерой предосторожности.

Рекомендации

  1. Проверка и отладка команд: Всегда проверяйте результат работы команды find без исполнения rm, чтобы убедиться, что будут удалены именно те файлы, которые вы хотите удалить. Например, используйте find . -type f -name "*1.mp3" -print для предварительного просмотра списка файлов.

  2. Резервное копирование: Перед массовым удалением файлов настоятельно рекомендуется создавать резервные копии данных, чтобы избежать случайной потери важной информации.

  3. Снятие ограничения -i: Когда вы уверены в точности поиска, опцию -i можно убрать, чтобы операция удаления проходила без запросов на подтверждение, ускоряя процесс.

Такое детализированное применение команды find позволяет эффективно управлять файлами в сложных структурах каталогов и избежать ошибок, связанных с несоответствующим использованием подстановочных символов.

Оцените материал
Добавить комментарий

Капча загружается...