Можно проверить использование:
for user in $(awk -F: '{print $1}' /etc/passwd);
do
printf "%-10s" "$user" ; su -c 'umask' -l $user 2>/dev/null
done
Чтобы постараться не проверять пользователя системы, сделайте:
for user in $(awk -F: '( $3 >= 500 ){print $1}' /etc/passwd);
do
printf "%-10s" "$user" ; su -c 'umask' -l $user 2>/dev/null
done
OutPut:
ram 0022
shyam 0022
suraj 0022
vinayak 0022
javed 0022
find . -depth -print0 | perl -0lne '
if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}'
Если ваш find
не поддерживает -print0
, вы можете заменить его на -exec printf '% s \ 0 '{} +
.
Идея состоит в том, чтобы напечатать список файлов с завершающим NUL (поскольку 0 - единственный байт, который не может встречаться в пути к файлу) и использовать perl
-n
] с параметром -0
, чтобы запустить некоторый код для каждого из этих имен файлов (с $ _
, установленным в имя файла).
С -depth
файлы печатаются перед их родительским каталогом. Мы удаляем только файлы или каталоги (при условии, что они пусты, поэтому важно обрабатывать список в порядке глубины
), если их путь содержит / Caches /
, за которым не следует / Снимки /
.
Я не колдун найти
, поэтому не хочу говорить, что вы не можете сделать это с найти
, но я знаю, что это может быть сделано с помощью пары строк баш
. Учитывая, что я правильно понимаю структуру вашего каталога:
#!/bin/bash
for i in Library/Caches/*; do
if [[ -d "$i" ]]; then
[[ "$i" =~ "Snapshots" ]] || echo "rm-ing $i" # change to rm -rf "$i" to use
fi
done
оператор for
возвращает каждый элемент в Library/Caches/
. Оператор если [[ -d "$i" ]]
проверяет, что каждый элемент является каталогом, и если это так, то проверяется его имя, чтобы посмотреть, содержит ли он "Снимки", [[ -d "$i" =~ "Снимки"]]
. Так как нет оператора для отрицания регексового совпадения, например !=~
, я использовал ||
для выполнения rm
, если предыдущая команда неудачна, например, имя каталога не содержит снимков.
Это будет выполняться на любой современной системе с использованием bash
, но она должна иметь bash
. Также вам может понадобиться поиграть со структурой каталогов, но это должно сделать это за вас.
Почему бы просто не найти то, что вам нужно, исключив то, что вы хотите сохранить?
Ищите файлы, а не каталоги:
find . -type f | grep Cashes | grep -v Snapshot | xargs rm
Таким образом, вы найдете все файлы из текущих каталогов, затем выберете только те файлы, которые находятся в каталогах Cashes
, затем вы исключите те файлы, которые находятся в каталоге Snapshot
, а затем удалите все остальное.
Вышеуказанное может оставить пустые каталоги, но можно поиграть с опциями find
, чтобы получить нужный результат.
cd ./Library/Caches
mv ./Snapshots ../
sh -c 'rm -rf -- .[!.]* *'
mv ../Snapshots ./
Вам не нужно устанавливать какие-либо постоянные параметры оболочки. Просто переместите каталог, удалите все и верните его обратно. Я использую глобус . [!.]
выше для обработки любых .files
и помещаю его в sh
, потому что bash
или zsh
, скорее всего, не будут правильно интерпретировать переносимый глобус оболочки. Но если нет .files
, вы можете использовать:
rm -rf -- *
.. вместо этого. Просто не делайте ни того, ни другого в любом каталоге, в котором вы не хотите, чтобы все было удалено.
Вы можете применить ту же логику рекурсивно - например, при наличии нескольких экземпляров ./ Caches / Snapshots
. Сначала создайте каталог для хранения в той же файловой системе, что и ./ Library /
:
mkdir -p hold ; hold=${PWD}/hold/Snapshots
Теперь найдите
все каталоги снимков
, затем сохраните их в другом месте и удалите остальные :
cd ./Library
find . -type d -name Snapshots -exec sh -c '
[ "$0" != "${0%/Caches/Snapshots}" ] && {
mv "$0" '"${hold}"' &&
( cd "${0%/*}" && rm -rf -- .[!.]* * ) &&
mv '"${hold}"' "$0"
}' \{\} \;
Первая часть: найти каталоги с именем cache и что-то с ними сделать
find . -name Caches -type d -exec … \;
Вторая часть: пройти по каталогу кеша и удалить все, но сохранить подкаталоги Snapshots
и их содержимое (а также пути, ведущие к ним). Выполните обход в глубину, чтобы каталоги можно было удалить, когда они станут пустыми.
find /path/to/Caches -depth -name Snapshots -type d -prune \
-o \( -type d -empty -o ! -type d \) -delete
Теперь объедините их вместе.
find . -name Caches -type d -exec
find {} -depth -name Snapshots -type d -prune \
-o \( -type d -empty -o ! -type d \) -delete
Меня немного смущает формулировка вопроса. Если вы хотите удалить все в каталоге ./ Library / Caches
, кроме одной папки с именем Snapshots
, нет необходимости использовать find
. В bash
оболочки оболочки являются самым простым способом:
shopt -s extglob # probably already enabled
echo Library/Caches/!(Snapshots)
Если при этом выводятся все файлы / каталоги, которые вы хотите удалить, замените echo
на rm -f - -
.
Если есть несколько каталогов Snapshots
на разных уровнях дерева каталогов ниже ./ Library / Caches
, которые вы хотите сохранить, то с помощью GNU найдите
вы можете сделать:
find Library/Caches ! -path '*Snapshots*'
Это должно распечатать все файлы / каталоги, за исключением тех, в пути которых есть Snapshots
. Он будет включать каталоги, которые содержат (или чьи дочерние содержат) каталоги моментальных снимков
, однако находят ... -delete
не удалит их, а вместо этого выведет сообщение об ошибке, что они не пустые. Когда вы будете счастливы, добавьте в конец -delete
.
Одно предостережение: при этом все файлы с именами Снимки
останутся нетронутыми. Если это проблема, вместо этого выполните:
find Library/Caches \( ! -path '*Snapshots*' -o -type f -name Snapshots \)
Снова добавьте -delete
, когда будете счастливы.