Как исключить файлы / каталоги из find с помощью аргумента программы в bash?

Моя находка выглядит очень просто:

find . -type f 

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

 bash myscript.sh -excl abcd 

Где a, b, c, d или любой следующий аргумент опции excl – это регулярное выражение, относящееся к определенным файлам или каталогам, которые я хочу исключить.

Поэтому, если я назвал программу таким образом:

 bash myscript.sh -excl *.sh somedir 

Я просто хочу найти игнорировать каталог somedir и все файлы с расширением .sh . Возможно ли это в bash?

Да, вы можете просто добавить -not -name если есть второй аргумент для вашего скрипта:

 #!/bin/bash targetDir="$1" exclude="$2" findString=" '$targetDir'" if [[ ! -z "$exclude" ]]; then findString="$findString -not -name '$exclude'" fi eval "find $findString" 

Например:

 $ ls file1 file1.sh file2 file2.sh file3.sh file4.sh file5.sh $ foo.sh . . ./file1 ./file2 ./file1.sh ./file4.sh ./file3.sh ./file5.sh ./file2.sh $ foo.sh . '*sh' . ./file1 ./file2 

Если вы хотите определить несколько шаблонов для исключения:

 #!/bin/bash targetDir="$1" findString=" '$targetDir'" shift exclude="'$1'" shift for i in "$@"; do exclude="$exclude -a -not -name '$i'"; done if [[ ! -z "$exclude" ]]; then findString="$findString -not -name $exclude" fi eval "find $findString" 

Решение с использованием массивов bash :

 #!/bin/bash declare -a find_arguments=( -type f ) for arg; do find_arguments+=( ! -name "$arg" ) done find . "${find_arguments[@]}" 

Если вы действительно хотите регулярное выражение, тогда измените имя на -regex но из вашего примера вы, похоже, хотите глотать. (BTW, -regex не POSIX, но поддерживается GNU find .)

демонстрация

 touch {a,b,c}{x,y,z} ./myscript.sh 'a*' '*z' 

Вывод:

 ./bx ./by ./cx ./cy 

Я оставил синтаксический анализ командной строки для -excl и т. Д., Так как вы не дали понять, как обычно выглядят параметры командной строки вашего сценария, если это действительно просто -excl тогда вы можете просто проверить его ( [[ "$1" = -excl ]] ), а затем shift .