Я создаю скрипт, который удаляет файлы, используя конфигурацию, содержащую Folder и File_Prefix.
Это будет файл конфигурации:
config.txt
/local/FolderA,App /local/FolderB,Log /local/FolderC,File
Вот мой сценарий:
file="local/config.txt" while IFS="," read -r folder prefix; do find %s -name %s* -type f -exec rm {} \ "$folder" "$prefix"; done < "$file"
Однако он не работает должным образом. Можете ли вы помочь в устранении неполадок? У меня возникли проблемы с назначением значений из IFS
команды.
решение1
Предположим, что ваш файл конфигурации не содержит полей со встроенными символами новой строки или запятыми, и предположим, что вы хотите удалить все файлы, имеющие указанный префикс имени файла, только в указанных каталогах (т.е. не рекурсивно):
#!/bin/sh
while IFS=, read -r directory prefix; do
rm -- "$directory/$prefix"*
done <config.txt
Это считывает первое поле, разделенное запятыми, в каждой строке в directory
переменную, а остальную часть строки в prefix
переменную. Затем это используется для удаления файлов. (См.Где задокументирован аргумент `--` (двойное тире)?для объяснения по поводу --
)
Если вам необходимо выполнить удаление рекурсивно, под каждым указанным путем к каталогу:
#!/bin/sh
while IFS=, read -r directory prefix; do
find "$directory" -name "$prefix*" -exec rm {} +
done <config.txt
Разница между этими двумя вариантами, помимо find
рекурсивного поиска, заключается в том, что один из них $prefix
будет использоваться так, как если бы это был шаблон подстановки в find
команде.
Обратите внимание, что *
при использовании необходимо заключать его в кавычки find
, чтобы оболочка не расширяла его до соответствующих имен в текущем каталоге, и это *
должно бытьнецитируемыйпри использовании rm
в первом цикле выше, так что оболочка расширяет его до всех соответствующих имен.
Если вынехотите выполнить удаление рекурсивно, но у вас так много файлов, соответствующих сгенерированным шаблонам, что первый цикл выдает ошибку «слишком длинный список аргументов», тогда вам, возможно, захочется сделать дополнительный внутренний цикл,
#!/bin/sh
while IFS=, read -r directory prefix; do
for pathname in "$directory/$prefix"*; do
rm -- "$pathname"
done
done <config.txt
или использовать find
ограниченный путь поиска верхнего уровня,
#!/bin/sh
while IFS=, read -r directory prefix; do
find "$directory" ! -path "$directory" -prune -name "$prefix*" -exec rm {} +
done <config.txt
решение2
Мы используем xargs для передачи путей к файлам из файла config.txt в исполняемый файл sh в его командной строке.
< config.txt xargs -rd'\n' sh -c '
for arg do
find "${arg%,*}" \
-name "${arg##*,}*" \
-type f \
-exec rm -f {} + ;
done
' xargs-sh