... согласно вашему комментарию к вопросу ...
pax -rws'/\.JPG$/.CAP&/' /root/of/copied/tree /dest/path
Если .jpg
и .JPG
- ваши единственные проблемы, это должно быть просто Работа.
Вы также можете добавить примитив rint p
к подстановке имени файла, чтобы получить список всех тех имен файлов, которые были изменены:
pax -rws'/\.JPG$/.CAP&/p' /root/of/copied/tree /dest/path
Насколько я могу судить, pax
уже должен быть установлен в системе OSX, так что в целом это должно быть довольно беспроблемным решением.
Однако, если проблема все-таки окажется более серьезной, вас также может заинтересовать, что pax
поддерживает ...
-i
Интерактивное переименование файлов или архивов члены. Для каждого члена архива, соответствующего операнду шаблона, или каждого файла, соответствующего файловому операнду,
pax
предложит/ dev / tty
указать имя файла, его режим файла и его модификацию. время.pax
затем прочитает строку из/ dev / tty
. Если эта строка пуста, элемент файла или архива пропускается. Если эта строка состоит из одной точки, файл или элемент архива обрабатывается без изменения его имени. В противном случае его имя заменяется содержимым строки.pax
немедленно завершит работу с ненулевым статусом выхода, если EOF будет (CTRL + D
) обнаружен при чтении ответа или если/ dev / tty
не может быть открыт для чтения и записи.
Если вашей целью является удаление всех файлов в массиве папок, другой альтернативой может быть передача массива в rm
вот так:
#!/bin/bash
$IMAGES_DIR="/Users/michael/scripts/imagefiles"
$BACKUP_DIR="/Users/michael/scripts/imagebackups"
#...
# to preserve whitespaces in path strings, add double quotes around each variable
array=( "$IMAGES_DIR" "$BACKUP_DIR" )
# this appends "/*" to the end of each dirname if you want to delete the contents of the directories
# without deleting the directories themselves
array=( "${array[@]/%//*}" )
# this will spread the array into multiple calls to rm
rm -rf ${array[@]}
Один пример вкладыша -:
rm -rf ${array[@]/%//*}
Но если вы хотите удалить папки, вы можете просто использовать
rm -rf ${array[@]}
Следует отметить одно различие с решением B-слоя , которое заключается в том, что хотя find
выводит любые ошибки при нахождении предоставленных путей, rm
в этом примере этого не делает.
РЕДАКТИРОВАТЬ:
Как указал kusalananda , важно отметить, что такое распространение массива может быть опасным, если в ваших путях есть пробелы или символы оболочки -. Чтобы избежать разбиения массива на эти символы, не забудьте добавить двойные кавычки вокруг переменных, добавленных в массив.
Опция -f
для rm
позволяет утилите не выдавать сообщения, если файловые операнды не существуют. Он также не выйдет с ошибкой.
Что возможно, происходит в вашем случае, так это то, что один или несколько каталогов пусты, за исключением файлов или каталогов со скрытыми именами, поэтому *
в конце вашего шаблона не расширяется до что-нибудь. Вы можете сделать так, чтобы глобус *
соответствовал скрытым именам в bash
, установив параметр оболочки dotglob
.
Вы также не должны помещать $
в имена переменных в присваиваниях, и вам необходимо заключать расширения переменных в двойные кавычки, чтобы избежать разделения слов и генерации имен файлов (подстановок ). Имена переменных должны быть в нижнем регистре, чтобы вы случайно не перепутали переменные среды или специальные переменные оболочки.
Альтернативная формулировка вашего кода, учитывающая эти вещи;
#!/bin/bash
shopt -s dotglob
images_dir="/Users/michael/scripts/imagefiles"
backup_dir="/Users/michael/scripts/imagebackups"
dirs=( "$images_dir" "$backup_dir" )
for dir in "${dirs[@]}"; do
rm -f "$dir"/*
done
Вышеприведенное попытается удалить все файлы из каталогов. Если каталоги имеют подкаталоги, вы получите сообщение об ошибке из rm
. Если вы хотите удалить их тоже, используйте -r
с rm
.
Не вызывать внешний процесс для проверки, а использовать внутреннюю функцию оболочки test
if test -d "$i"; then # check that directory exists
Между тестом и вызовом rm возможно, что другие процессы уже стерли каталог, поэтому rm выйдет из строя. Вы можете использовать переключатель-f или перенаправить ошибки
/bin/rm "$i/*" 2> /dev/null # remove the files