O script pode ser reduzido para:
directory=$1
fileName=$2
shift 2
a="$*" b="${*#.}"
(( ${#a} - ${#b} - $# )) && echo "some extension(s) is(are) missing a leading dot." >&2
fileExtensions="$(IFS=\|; echo "${*#.}")"
find "$directory" -name "$fileName*" -regextype posix-egrep -regex ".*\.($fileExtensions)$"
Por padrão, find aceita regex do tipo emacs, para usar esse tipo várias barras invertidas são necessárias, como \|
. Isso poderia ser evitado usando um tipo diferente de regex (como acima).
Em que ${*#.}
remove o ponto inicial (se existir) e une todos os "Parâmetros posicionais" restantes com o valor do primeiro caractere do IFS, que foi definido como |
para a execução da subshell.
Apenas uma atribuição de variável com uma "Expansão de Parâmetro" é tudo o que é necessário.
EDITAR
O (( ${#a} - ${#b} - $# ))
é usado para verificar se todas as extensões fornecidas na lista de argumentos começam com um ponto.
A contagem de caracteres ( ${#a}
) de todos os argumentos concatenados ( a=$*
)
deve ser igual a um
a contagem de caracteres ( ${#b}
) de todos os argumentos concatenados (um ponto principal removido) ( b=${*#.}
)
mais e mais
o número de argumentos ( $#
).
${#a} == ${#b} + $#
Se e somente se todos os argumentos tiverem um ponto inicial.
Como teste aritmético:
(( ${#a} - (${#b} + $#) ))
Ou também:
(( ${#a} - ${#b} - $# )) && echo "missing leading dot(s)."
Editar II
A lista de extensões dadas nos argumentos da linha de comando é processada aqui:
fileExtensions="$(IFS=\|; echo "${*#.}")"
Veja como funciona, de dentro para fora:
$* # This generates a string of all positional arguments using IFS.
De LESS=+'/Special Parameters' man bash
:
That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable.
Em seguida, usamos "expansão de parâmetro" para cortar a frente de cada argumento posicional:
${parameter#word} # used as ${*# } above.
De LESS=+/'parameter#word' man bash
:
If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.
O word
na expansão anterior está definido para um ponto .
, removendo assim os pontos na frente de todos os parâmetros posicionais.
Como o IFS nesse ponto começa com um caractere |
, isso é usado para criar uma string com |
como o separador para a lista de parâmetros que foi distribuída de um ponto na frente.
Essa string é fornecida ao comando echo para que seja impressa.
Mas antes que o comando echo seja executado, a variável $IFS
é definida como |
.
Isso é empacotado dentro de uma execução de comando $(…)
(para criar um sub shell que irá esquecer a mudança para o IFS quando ele terminar).
Em seguida, atribuímos a string a uma variável:
fileExtensions="$(IFS=\|; echo "${*#.}")"
Em resumo: isso transforma .c .h .txt
em c|h|txt
.