Используйте находят, чтобы найти определенный каталог и удалить все файлы в нем кроме одного каталога

Можно проверить использование:

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
5
29.06.2014, 14:47
6 ответов
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 / , за которым не следует / Снимки / .

6
27.01.2020, 20:33

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

#!/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. Также вам может понадобиться поиграть со структурой каталогов, но это должно сделать это за вас.

2
27.01.2020, 20:33

Почему бы просто не найти то, что вам нужно, исключив то, что вы хотите сохранить?

Ищите файлы, а не каталоги:

find . -type f | grep Cashes | grep -v Snapshot | xargs rm

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

Вышеуказанное может оставить пустые каталоги, но можно поиграть с опциями find, чтобы получить нужный результат.

-1
27.01.2020, 20:33
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"
}' \{\} \;
0
27.01.2020, 20:33

Первая часть: найти каталоги с именем 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
0
27.01.2020, 20:33

Меня немного смущает формулировка вопроса. Если вы хотите удалить все в каталоге ./ 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 , когда будете счастливы.

7
27.01.2020, 20:33

Теги

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