очистить несколько каталогов с помощью rm

... согласно вашему комментарию к вопросу ...

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 не может быть открыт для чтения и записи.

4
24.12.2017, 04:07
3 ответа

Если вашей целью является удаление всех файлов в массиве папок, другой альтернативой может быть передача массива в 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 , важно отметить, что такое распространение массива может быть опасным, если в ваших путях есть пробелы или символы оболочки -. Чтобы избежать разбиения массива на эти символы, не забудьте добавить двойные кавычки вокруг переменных, добавленных в массив.

-1
27.01.2020, 20:59

Опция -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.

0
27.01.2020, 20:59

Не вызывать внешний процесс для проверки, а использовать внутреннюю функцию оболочки test

if test -d "$i"; then # check that directory exists

Между тестом и вызовом rm возможно, что другие процессы уже стерли каталог, поэтому rm выйдет из строя. Вы можете использовать переключатель-f или перенаправить ошибки

/bin/rm "$i/*" 2> /dev/null # remove the files

0
27.01.2020, 20:59

Теги

Похожие вопросы