Bash проверяет, существует ли регулярное выражение, соответствующее файлу, и присваивает имя файла переменной

#regex #bash

#регулярное выражение #удар

Вопрос:

Я ищу быстрый, короткий и переносимый способ проверить, существует ли файл, соответствующий регулярному выражению, в текущем рабочем каталоге, и если да, то присвоить его базовое имя переменной (env(ironment)?|requirements).ya?ml для дальнейшей обработки. ………. $FILE

В принципе, я хотел бы объединить получение дескриптора в

 for FILE in environment.yml env.yml requirements.yml environment.yaml env.yaml requirements.yaml; do
  if [ -e $FILE ]; then
    ...
  fi
done
  

с использованием регулярного выражения, как в

 if test -n "$(find -E . -maxdepth 1 -regex '.*(env(ironment)?|requirements).ya?ml' -print -quit)"
then
  ...
fi
  

Ответ №1:

Вставьте его в переменную:

 file="$(find -E . -maxdepth 1 -regex '.*(env(ironment)?|requirements).ya?ml' -print -quit)"

if [ -n "$file" ]
then
  echo "I found $file"
else
  echo "No such file."
fi
  

В качестве альтернативы вы можете сохранить цикл и сократить его, используя расширение в виде фигурных скобок:

 for file in {env{,ironment},requirements}.{yml,yaml} 
do
  if [ -e "$file" ]
  then
    echo "Found $file"
  else
    echo "There is no $file"
  fi
done
  

или сопоставьте файлы напрямую, используя extglob от bash:

 shopt -s nullglob
for file in @(env?(ironment)|requirements).y?(a)ml
do
  echo "Found $file"
done
  

Комментарии:

1. Действительно ли первая форма ( test -n ) работает для нескольких файлов?

2. @jpaugh Да, хотя test -e не стал бы. Из-за -quit он находит не более одного файла, хотя

3. Пропустил это. Спасибо!

4. «тот другой парень» знает о сценариях больше, чем я планирую! 🙂