Используя совпадение, чтобы найти подстроки в строках только с bash
Хотя я почти уверен, что это было охвачено, я не могу найти ничего конкретного. Когда я продолжаю свое путешествие по изучению bash, я продолжаю находить части, где я озадачен тем, почему все происходит так, как они делают.
Поиск и замена или просто соответствие подстрок в строках, скорее всего, одно из первых, что вы делаете при написании скриптов. Но, пытаясь придерживаться одного языка или набора инструментов, трудно сделать в bash, так как вы можете решить большинство проблем несколькими способами. Я прилагаю все усилия, чтобы оставаться на низком уровне с bash. Я столкнулся с проблемой, что мне нужно, чтобы кто-то объяснил мне.
Выполняя подстроку, поиск в bash с совпадением дает мне разные результаты в зависимости от регулярного выражения, которое я использую, и я не уверен, почему.
#!/bin/bash
Stext="Hallo World"
echo `expr "$Stext" : '^\(.[a-z]*\)'` # Hallo
echo `expr "$Stext" : '.*World'` # 11
Хотя оба ищут слово, я думаю, оба не возвращают то, что они находят. Зачем?
Ответы
Ответ 1
Оба выражения эквивалентны, разница заключается в регулярном выражении, которое вы используете:
$ echo `expr "$Stext" : '^\(.[a-z]*\)'`
Hallo
$ echo `expr "$Stext" : '^.[a-z]*'`
5
$ echo `expr "$Stext" : '\(.*World\)'`
Hallo World
$ echo `expr "$Stext" : '.*World'`
11
Как вы можете видеть, круглые скобки - это то, что заставляет изменить либо длину совпадения, либо совпадение.
В в главе 10 расширенного руководства Bash -Scripting Guide можно найти несколько примеров.
Ответ 2
Вы можете использовать переменную BASH_REMATCH
в bash
, чтобы получить согласованную строку:
$ Stext="Hallo World"
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH
Hallo
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]}
Hallo
Подстроки, совпадающие с подвыражениями в скобках в регулярном выражении, сохраняются в переменной массива BASH_REMATCH. Элемент BASH_REMATCH с индексом 0 является частью строки, соответствующей всему регулярному выражению. Элемент BASH_REMATCH с индексом n является частью строки, соответствующей n-му подвыражению в скобках.
Ответ 3
Я сделал эту простую функцию:
match() {
TRUE=1
FALSE=0
match_return=0
echo $1 | grep $2 >/dev/null
[ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE
}
Использование:
match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope"
весь код: https://gist.github.com/TeeBSD/5121b3711fad40a09455
Ответ 4
Для быстрого поиска строк... Один из вариантов - grep.
Если он не найден, возвращается пустым, иначе оно соответствует:
found=`echo $big | grep -e $short`
if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi