bash build список опций для поиска - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь создать список параметров в массиве bash для find, чтобы найти определенные файлы. Рассмотрим каталог со следующими файлами:

A_foo_0
A_foo_1
A_bar_0
B_foo_0
B_foo_1
B_bar_0
C_foo_0
C_foo_1
C_bar_0

Мой скрипт программно определил, что *foo* файлы должны быть найдены при поиске, но не файлы, которые начинаются с A или C. Таким образом, должны быть найдены только B_foo_0 и B_foo_1, как показывает следующий ручной вызов find:

$ find ./ -name "*foo*" ! -name "A*" ! -name "C*"
./B_foo_1
./B_foo_0

Но мне нужно выучить префиксы для динамического исключения, поэтому у меня есть массив, определяющий, какие префиксы следует исключить:

declare -a excludeArray
excludeArray+=(A)
excludeArray+=(C)

Я хочу превратить это в ! -name "A*" and ! -name "C*" и передать, чтобы найти что-то вроде этого:

excludeOptions=( "${excludeArray[@]/%/\*\"}" )  # Append *" to each element
excludeOptions=("${excludeOptions[@]/#/ ! -name \"}") # Prepend ! -name " to each element

Теперь, если я повторю это, это выглядит довольно хорошо:

echo "${excludeOptions[@]}"
 ! -name "A*"  ! -name "C*"

Но когда я пытаюсь использовать его с find, я получаю следующее:

$ find ./ -name "*foo*" "${excludeOptions[@]}"
find: paths must precede expression:  ! -name "A*"

Включение режима отладки показывает, что проблема, вероятно, связана с цитированием элементов:

$ set -x
$ find ./ -name "*foo*" "${excludeOptions[@]}"
+ find ./ -name '*foo*' ' ! -name "A*"' ' ! -name "C*"'
find: paths must precede expression:  ! -name "A*"

$ find ./ -name "*foo*" ${excludeOptions[@]}
+ find ./ -name '*foo*' ' ! -name "A*"' ' ! -name "C*"'
find: paths must precede expression:  ! -name "A*"

Если я построю массив следующим образом, он будет работать:

$ excludeOptions=( ! -name "A*" ! -name "C*")
$ find ./ -name "*foo*" "${excludeOptions[@]}"
+ find ./ -name '*foo*' '!' -name 'A*' '!' -name 'C*'
./B_foo_1
./B_foo_0

Но я не могу понять, как это сделать динамически.

1 Ответ

0 голосов
/ 07 ноября 2018

Нет простого способа добавить или добавить отдельные слова к существующему содержимому массива. Вам понадобится петля.

excludeOptions=()
for e in "${excludeArray[@]}"; do excludeOptions+=(! -name "$e*"); done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...