Удалите все файлы кроме определенного подкаталога с находкой

Я думаю, что сопоставитель отступает к вторичному (или третичный или...) DNS, только если первое (или второй или...) перестало работать.

В этом случае запрос не перестал работать, он правильно возвращается NXDOMAIN, т.е. доменное имя не существует.

Если Вы действительно хотите использовать DNS Google (или какой-либо другой DNS в этом отношении) для разрешения внешних доменов (вместо внутренних серверов имен), можно настроить серверы 10.3.x.x и 10.219.x.x быть authoritative для Ваших внутренних имен только и передать все другие запросы внешнему DNS, затем используйте свои внутренние серверы имен в качестве Ваших единственных серверов имен на Ваших внутренних компьютерах.

10
02.02.2015, 20:48
3 ответа

TL; DR: лучший способ состоит в том, чтобы использовать -exec rm вместо -delete.

find a \( -name b -prune \) -o -type f -exec rm {} +

Объяснение:

Почему действительно находит, жалуются, когда Вы пытаетесь использовать -delete с -prune?

Короткий ответ: потому что -delete подразумевает -depth и -depth делает -prune неэффективный.

Прежде чем мы придем к длинному ответу, сначала наблюдают поведение находки с и без -depth:

$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2

Нет никакой гарантии о порядке в единственном каталоге. Но существует гарантия, что каталог обрабатывается перед его содержанием.Примечание: foo/ перед любым foo/* и foo/bar перед любым foo/bar/*.

Это может быть инвертировано с -depth.

$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/

Отметьте это теперь все foo/* появитесь прежде foo/. То же с foo/bar.

Более длинный ответ:

  • -prune предотвращает находят от убывания в каталог. Другими словами, -prune пропускает содержание каталога. В Вашем случае -name b -prune предотвращает находят от убывания в любой каталог с именем b.
  • -depth делает находят для обработки содержания каталога перед самим каталогом. Это означает к тому времени, когда находят, добирается для обработки записи каталога b его содержание было уже обработано. Таким образом -prune неэффективно с -depth в действительности.
  • -delete подразумевает -depth таким образом, это может удалить файлы сначала и затем пустой каталог. -delete отказывается удалять непустые каталоги. Я предполагаю, что было бы возможно добавить опцию вызвать -delete удалить непустые каталоги и/или предотвратить -delete подразумевать -depth. Но это - другая история.

Существует другой способ достигнуть того, что Вы хотите:

find a -not -path "*/b*" -type f -delete

Это может или не может быть легче помнить.

Эта команда все еще убывает в каталог b и обрабатывает каждый файл в нем только для -not отклонить их. Это может быть проблемой производительности если каталог b огромно.

-path работы по-другому, чем -name. -name только соответствия против имени (файла или каталога), в то время как -path соответствует против всего пути. Например, наблюдайте путь /home/lesmana/foo/bar. -name -bar будет соответствовать, потому что имя bar. -path "*/foo*" будет соответствовать потому что строка /foo находится в пути. -path имеет некоторую запутанность, которую необходимо понять перед использованием его. Прочитайте страницу справочника find для получения дополнительной информации.

Остерегайтесь этого, это не является на 100% надежным. Существуют возможности "ложных положительных сторон". Путем команда записана выше его, пропустит любой файл, который имеет любой родительский каталог, с которого запускается имя b (положительный). Но это также пропустит любой файл, с которого запускается имя b независимо от положения в дереве (положительная ложь). Это может быть зафиксировано путем записи лучшего выражения, чем "*/b*". Это оставляют как осуществление для читателя.

Я предполагаю, что Вы использовали a и b поскольку заполнители и настоящие имена больше похожи allosaurus и brachiosaurus. Если Вы помещаете brachiosaurus вместо b затем количество ложных положительных сторон будет решительно уменьшено.

По крайней мере, ложные положительные стороны не будут удалены, таким образом, это будет не как трагичное. Кроме того, можно проверить на ложные положительные стороны первым выполнением команды без -delete (но не забудьте помещать подразумеваемое -depth) и исследуйте вывод.

find a -not -path "*/b*" -type f -depth
10
27.01.2020, 20:02
  • 1
    -not -path была просто вещь! Спасибо за щедрое объяснение! –  forthrin 18.08.2013, 21:55
  • 2
    Некоторая разработка, на почему -not -path работы, в то время как -prune не делает было бы полезно. Почему может -not -path сосуществуйте с -depth? –  Faheem Mitha 02.02.2015, 21:07

Просто используйте rm вместо -delete:

find a -name b -prune -o -type f -exec rm -f {} +
3
27.01.2020, 20:02
  • 1
    , Может Вы уточнять почему rm работы и delete не? –  Faheem Mitha 02.02.2015, 20:50
  • 2
    О, я предполагаю, возможно, потому что "-удаляют, отказывается удалять непустые каталоги". для заключения в кавычки @lesmana. Так отказывается удалять непустые каталоги. Но rm не имеет той проблемы. Но, независимо, разработка была бы хорошей вещью. –  Faheem Mitha 02.02.2015, 20:53
  • 3
    @FaheemMitha, ответ на это находится в вопросе. -delete подразумевает -depth, который, очевидно, не может работать с -prune. -path работы, но не останавливается find от убывания в каталогах, которые это не должно исследовать. –  Stéphane Chazelas 02.02.2015, 21:23

Приведенные выше ответы и пояснения оказались очень полезными.

Я использую обходные пути "-exec rm {} +" или "-не -путь... -удалить", но они могут быть намного медленнее, чем "найти... -удалить". Я видел, как "найти... -удалить" выполнялось в 5 раз быстрее, чем "-exec rm {} +" в глубоких каталогах в файловой системе NFS.

Решение ' -not path " имеет очевидные накладные расходы, связанные с просмотром всех файлов в исключенных каталогах и ниже.

Команда «find.. -exec rm {} +» вызывает rm, который выполняет системные вызовы:

fstatat(AT_FDCWD, path...); 
unlinkat(AT_FDCWD, path, 0)

Функция «найти -удалить» выполняет системные вызовы:

 fd=open(dir,...);
 fchdir(fd); 
 fstatat(AT_FDCWD, filename,...)
 unlinkat(dirfd, filename,...)

Таким образом, команда «-exec rm {}+» rm выполняет поиск полного пути к индексному узлу дважды дважды для каждого файла, но «find -delete» выполняет статистику и отменяет связь имени файла в текущем каталоге. Это большая победа, когда вы удаляете много файлов в одном каталоге.

(включен режим ноющего (извините))

Кажется, что дизайн взаимодействия между -depth, -delete и -prune без необходимости устраняет наиболее эффективный способ выполнения общего действия «удалить файлы, кроме тех, которые находятся в -prune каталогах»

Комбинация «-type f -delete» должна работать без глубины -, поскольку она не пытается удалить каталоги. В качестве альтернативы, если бы «найти» имело действие «-удалить файл», которое говорит не удалять каталоги, -глубину не нужно было бы подразумевать.

Вызовы команды xargs или find -exec для команды rm можно было бы ускорить, если бы rm имел возможность сортировать имена файлов, открывать каталоги и выполнять unlinkat (dir _fd,filename )вместо отсоединение полных путей. Он уже делает unlinkat (dir _fd,filename )при рекурсии по каталогам с опцией -r.

(режим визга выключен)

1
27.01.2020, 20:02

Теги

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