Chciałbym powiedzieć, czy ciąg $string
pasowałby do wzorca globu $pattern
. $string
może, ale nie musi, być nazwą istniejącego pliku. W jaki sposób mogę to zrobić?
Przyjmij następujące formaty dla moich ciągów wejściowych:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
Chciałbym znaleźć idiom bash, który określa, czy $string
będzie dopasowane $pattern1
, $pattern2
lub jakiegokolwiek innego arbitralnego glob wzorca. Oto, co próbowałem do tej pory:
[[ "$string" = $pattern ]]
To prawie działa, ale
$pattern
jest interpretowane jako wzorzec łańcucha, a nie jako wzorzec globalny.[ "$string" = $pattern ]
Problem z tym podejściem polega na tym, że
$pattern
jest on rozwijany, a następnie przeprowadzane jest porównywanie ciągów znaków$string
z rozszerzeniem$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
Ten działa, ale tylko wtedy, gdy
$string
zawiera plik, który istnieje.[[ $string =~ $pattern ]]
To nie działa, ponieważ
=~
operator powoduje$pattern
interpretację jako rozszerzone wyrażenie regularne, a nie wzorzec globalny lub symbol wieloznaczny.
ls /foo/*
teraz możesz dopasować
foo/{bar,baz}
tak naprawdę jest to rozwinięcie nawiasów klamrowych (a nie rozszerzenie parametrów), podczas gdy foo/*
jest to rozwinięcie nazwy ścieżki. $string
to rozszerzenie parametrów. Wszystko to odbywa się w różnym czasie i za pomocą różnych mechanizmów.
case
instrukcja wykonuje rozszerzenie nazwy ścieżki („globbing”) zgodnie z instrukcją Bash.
{bar,baz}
to nie jest wzór. To rozszerzenie parametrów. Subtelna, ale krytyczna różnica w tym{bar,baz}
jest bardzo wcześnie rozszerzona na wiele argumentówbar
ibaz
.