Как сделать текстовое совпадение в bash
Я пытаюсь найти хороший способ проверки текста, чтобы установить переменную. Например, чтобы выполнить логику: "если строка версии 1.x, тогда установите флаг". Один из способов сделать это:
versionFlag="0"
if grep -q "^1.*" versionfile; then
versionFlag="1"
fi
который немного многословен. Если я хочу включить несколько возможностей, то это проще:
case `grep "^1.*" versionfile` in
1.*)
echo "version 1"
;;
...
esac
Но есть ли хороший однострочный способ просто установить флаг в значение true или false, если какой-либо текст соответствует регулярному выражению или подстановочному знаку?
4 ответа
versionFlag=`grep "^1.*" /tmp/test | wc -l`
versionFlag
затем устанавливается на 0. Любые данные в тестовых матчах, versionFlag
устанавливается на количество совпадающих строк, поэтому
if [ $versionFlag == 0 ] ; then
echo false
else
echo true
fi
редактировать: это можно сделать еще проще
versionFlag=$(grep "^1.*" /tmp/test -c)
который вернет количество экземпляров в файле
Вы можете сделать что-то подобное в bash 3.x (старые версии не поддерживают сопоставление регулярным выражениям)
version=`cat versionfile`
[[ $version =~ "^1.*" ]] && versionFlag=1
В bash нет тернарного оператора (например,?:), так что вы застряли в своем if, а затем строите несколько строк. Вы можете использовать другой язык с троичным оператором (например, PERL).
Имейте в виду, что многие люди не рекомендуют использовать троичные операторы, так как их не так просто прочитать в коде - другими словами, ваши комментарии заканчиваются дольше, чем было бы несколько строк кода.
Я сомневаюсь, что есть какой-то выигрыш в производительности любого метода.
Собственно, эта конструкция:
[[ $version =~ ^1\.+ ]] && versionFlag=1
легко расширяется для поддержки случая отсутствия совпадений; просто сделай это:
[[ $version =~ ^1\.+ ]] && versionFlag=1 || versionFlag=0
Кстати, обратите внимание на изменение от '*' до '+' в регулярном выражении. Используя звездочку, регулярное выражение по-прежнему будет некорректно соответствовать значению версии "10". (Модификатор '*' означает "соответствовать нулю или нескольким вхождениям", т. Е. Вам все еще не нужно иметь десятичную точку; модификатор "+" означает "соответствовать одному или нескольким вхождениям".) Однако внесение этого изменения будет, означает, что "1" (т. е. значение без десятичной дроби) не будет совпадать; это может или не может быть проблемой для вашего приложения.
Есть также способ сделать это без использования оператора regex-match, если у вас его нет; попробуй это:
[[ ${version#1.} != ${version} ]] && versionFlag=1 || versionFlag=0
Это просто сопоставление с шаблоном, а не регулярное выражение, поэтому, если вам действительно нужна функциональность регулярного выражения, это не сработает, но для простых вещей это здорово. (Если вы не знакомы с этой формой расширения параметров, конструкция "${version#1.}" Раскрывается до значения "version", но с шаблоном post-'#', удаленным из начала значения если он был там изначально. Пример: если "версия" имеет значение "1.03", результатом "${version#1.}" будет "03". Поскольку это отличается от исходного значения, "!=" тест пройден успешно.)