Найти команду, которая исключает пути, перечисленные в файле

ntpd должен идти в ногу со словарной инфраструктурой серверов NTP, и у него есть алгоритмы для компенсации / расчета / учета потерь / RTT пакетов UDP через Интернет и распространение времени по слоям. Stratum 1 NTP-серверы обычно подключены к атомным часам. date более чем достаточно для разрешения 1.

2
13.09.2018, 21:13
3 ответа

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

#!/bin/sh

set --

while IFS= read -r path; do
    set -- "$@" -o -path "$path"
done

shift   # remove initial "-o" from $@

find. -type d ! '(' "$@" ')'

Вы бы запустили это с помощью

./script.sh <paths.txt

где paths.txtможет выглядеть как

*/.git
*/.git/*
*/.vscode
*/.vscode/*
*/node_modules
*/node_modules/*
*/Image
*/Image/*
*/Rendered
*/Rendered/*
*/iNotebook
*/iNotebook/*
*/GeneratedTest
*/GeneratedTest/*
*/GeneratedOutput
*/GeneratedOutput/*
*/*_files

Или, поскольку все ваши шаблоны путей в основном являются именами каталогов:

#!/bin/sh

set --

while IFS= read -r dirname; do
    set -- "$@" -o '(' -name "$dirname" -prune ')'
done

shift   # remove initial "-o" from $@

find. -type d ! '(' "$@" ')'

с файлом шаблона, содержащим

.git
.vscode
node_modules
Image
Rendered
iNotebook
GeneratedTest
GeneratedOutput
*_files

Этот вариант кода не позволит findдаже спускаться в каталоги, соответствующие шаблонам в файле, в то время как первый скрипт (, а также ваш код )будет проверять шаблоны -pathна соответствие всему в исключенных каталогах, независимо от того, что вас ничего не интересует ниже этих путей.

3
27.01.2020, 21:53

Вы можете использовать grepи findс -execдля фильтрации файлов по списку путей либо в виде регулярных выражений, либо фиксированных строк. Адаптируя свой пример, создайте файл с именем paths, содержащий

/.git$
/.git/
/.vscode$
/.vscode/
/node_modules$
/node_modules/
/Image$
/Image/
/Rendered$
/Rendered/
/iNotebook$
/iNotebook/
/GeneratedTest$
/GeneratedTest/
/GeneratedOutput$
/GeneratedOutput/
/.*_files$

Затем запустите

find /your/search/path -type d ! -exec sh -c "echo {} | grep -q -f paths" \; -print

Он ищет каталоги в /your/search/pathи для каждого найденного использует grep, чтобы определить, соответствует ли он шаблону в paths; если это не так, он печатает это. Это предназначено в качестве базы для расширения; если вас интересуют только пути к каталогам, которые не соответствуют шаблонам в файле, и ни один из путей не охватывает несколько строк, вы можете опубликовать -обработку вывода, используя один grepвызов:

find /your/search/path -type d | grep -v -f paths

Если вас вообще не интересуют определенные пути (, то есть ваши шаблоны всегда соответствуют имени каталога, а затем всему, что находится в этом каталоге ),вы могли бы сделать вещи проще, обрезав:

find /your/search/path -type d \( -exec sh -c "echo {} | grep -q -f paths" \; -prune -o -print \)

со следующим содержимым в путях:

/.git$
/.vscode$
/node_modules$
/Image$
/Rendered$
/iNotebook$
/GeneratedTest$
/GeneratedOutput$
/.*_files$
2
27.01.2020, 21:53

Что можно сделать, так это создать команду, используя awkи передать ее в findкак переменную в сценарии-оболочке или функции оболочки

p=$( awk '{printf "-not -path %s ",$0}' "$1" )
find "$PWD"  $p -type d

И назовите его ./find_wrapper.sh paths.txt, где path.txt— список путей в кавычках.

'*/.git'
'*/.git/*'
'*/.vscode'
'*/.vscode/*'
'*/node_modules'
'*/node_modules/*'
'*/Image'
...

Почему так сделано? Причина, по которой awkстроит одну целую строку, заключается в том, что нет причин делать это в скрипте -, продолжение строки \предназначено для того, чтобы команда выглядела более организованной, но функционально это не дает никаких преимуществ. $pне заключено в кавычки, так как мы действительно хотим здесь разделить слова. В противном случае findвидит его как одну гигантскую строку, а не как отдельные флаги и аргументы. Что касается одинарных кавычек, это , чтобы избежать эффекта глобуса в двойных кавычках.

В качестве альтернативы в качестве конвейера

awk '{printf "-not -path %s ",$0}' "$1" | xargs -L 1  find "$PWD" -type d 
1
27.01.2020, 21:53

Теги

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