Построить список исключений каталога программно для команды Find (Bash) - PullRequest
0 голосов
/ 03 июля 2018

У меня есть массив каталогов, которые нужно исключить из результата моей команды поиска, что-то вроде EXCLUDE=("foo" "bar").

Я могу запустить это из интерактивного терминала следующим образом:

find . -name 'hvr.yml' -not -path "foo/*" -not -path "bar/*"

И поэтому я попытался создать аргумент так:

getServersToCheck() {

    # Build command arguments to exclude given dirs
    local exclude_command="-not -path"
    local excount=${#EXCLUDE[@]}
    for ((i=0;i<excount;i++)); do
        EXCLUDE[i]="${exclude_command} ${EXCLUDE[i]}/*"
    done

    find . -name 'hvr.yml' "${EXCLUDE[@]}"
}

Но это приводит к тому, что find выдает неизвестную ошибку предиката: '-not -path foo / *'

Есть ли способ достичь этого? Когда я повторяю команду, она выглядит правильно, но должны быть некоторые правила синтаксиса bash, которые заставляют это работать не так, как я ожидаю.

UPDATE:

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

find . -name hvr.yml -not -path '"foo/*"' -not -path '"bar/*"'

Одиночные кавычки, возможно, являются проблемой

Удаление \" и запуск с помощью xtrace показывает, что глобализация применяется в цикле for, в результате чего:

find . -name hvr.yml -not -path "foo/fileinfoo" "foo/somethingelseinfoo" -not -path "bar/*" "bar/fileinbar" "bar/otherfilesinbar"

Итак, find жалуется на случайные пути в качестве аргументов.

Есть ли способ развернуть массив EXCLUDE и добавить / * в конец каждого элемента команды?

1 Ответ

0 голосов
/ 05 июля 2018

Нашел альтернативное решение того, чего я пытался достичь, используя grep:

EXCLUDE=("abc" "def")

getPaths() {
    local exclude_count=${#EXCLUDE[@]}
    if [ $exclude_count -eq 0 ]; then
        find . -name $FILENAME | tr '\n' ' '
        return $?
    fi

    # Concat excluded servers as grep regex
    local regex="(${EXCLUDE[0]}"
    for ((i=1;i<exclude_count;i++)); do
        regex="${regex}|${EXCLUDE[i]}"
    done
    regex="${regex})"

    find . -name $FILENAME | grep -Ev "${regex}" | tr '\n' ' '
    return $?
}
  • Если исключение пусто, запускается обычная команда поиска.
  • В противном случае он создает регулярное выражение для фильтрации grep, которое в этом примере выглядит как (abc | def).
...