Я хотів би сказати, чи буде рядок $string
узгоджений з глобальним шаблоном $pattern
. $string
може бути, а може не бути іменем існуючого файлу. Як я можу це зробити?
Прийміть наступні формати для моїх вхідних рядків:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
Я хотів би знайти Баш ідіому , який визначає , якщо $string
буде супроводжуватися $pattern1
, $pattern2
або будь-яким іншим довільним шаблоном Глоб. Ось що я спробував поки що:
[[ "$string" = $pattern ]]
Це майже працює, за винятком того, що
$pattern
інтерпретується як рядковий візерунок, а не як глобальний шаблон.[ "$string" = $pattern ]
Проблема такого підходу полягає в тому, що
$pattern
розгортається, а потім проводиться порівняння рядків між$string
і розширенням$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
Цей працює, але тільки якщо
$string
містить файл, який існує.[[ $string =~ $pattern ]]
Це не працює, тому що
=~
оператор спричиняє$pattern
інтерпретацію як розширений регулярний вираз, а не глобул або шаблону підстановки.
ls /foo/*
зараз ви можете
foo/{bar,baz}
насправді є розширенням дужок (а не розширенням параметрів), а foo/*
є розширенням імені шляху. $string
- це розширення параметрів. Все це робиться в різний час і за різними механізмами.
case
оператор виконує розширення імені Pathname ("глобалізація") відповідно до посібника Bash.
{bar,baz}
це не зразок. Це розширення параметрів. Тонка, але критична різниця в цьому{bar,baz}
розгортається дуже рано на кілька аргументів,bar
іbaz
.