Gostaria de dizer se uma string $string
seria correspondida por um padrão glob $pattern
. $string
pode ou não ser o nome de um arquivo existente. Como posso fazer isso?
Suponha os seguintes formatos para minhas seqüências de caracteres de entrada:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
Eu gostaria de encontrar uma linguagem bash que determina se $string
seria acompanhado por $pattern1
, $pattern2
ou qualquer outro padrão glob arbitrária. Aqui está o que eu tentei até agora:
[[ "$string" = $pattern ]]
Isso quase funciona, exceto que
$pattern
é interpretado como um padrão de cadeia e não como um padrão glob.[ "$string" = $pattern ]
O problema com essa abordagem é que
$pattern
é expandido e a comparação de cadeias é executada entre$string
e a expansão de$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
Este funciona, mas somente se
$string
contém um arquivo que existe.[[ $string =~ $pattern ]]
Isso não funciona porque o
=~
operador faz$pattern
com que seja interpretado como uma expressão regular estendida, não como um padrão glob ou curinga.
ls /foo/*
agora você pode combinar em um
foo/{bar,baz}
na verdade é uma expansão entre chaves (não uma expansão de parâmetro) enquanto foo/*
é uma expansão de nome de caminho. $string
é expansão de parâmetro. Tudo isso é feito em momentos diferentes e por mecanismos diferentes.
case
instrução executa Expansão do nome do caminho ("globbing") conforme o manual do Bash.
{bar,baz}
não é um padrão. É expansão de parâmetros. A diferença sutil, porém crítica,{bar,baz}
é expandida muito cedo em vários argumentos,bar
ebaz
.