Использование match для поиска подстрок в строках только с bash

хотя я почти уверен, что это было покрыто, я не могу найти ничего конкретного для этого. По мере того, как я продолжаю свое путешествие по изучению bash, я продолжаю находить части, где я озадачен тем, почему все происходит так, как они делают.

поиск и замена или просто совпадение подстрок в строках, скорее всего, одно из первых, что вы делаете при написании сценариев. Но, пытаясь придерживаться одного языка или набора инструментов, трудно сделать в bash, так как вы можете решить большинство проблема во многих отношениях. Я делаю все возможное, чтобы оставаться на как можно более низком уровне с bash. Я столкнулся с проблемой, которую мне нужно, чтобы кто-то объяснил мне.

выполнение подстроки поиск в bash с match дает мне разные результаты в зависимости от регулярного выражения, которое я использую, и я не уверен, почему.

#!/bin/bash
Stext="Hallo World"
echo `expr "$Stext" : '^(.[a-z]*)'` # Hallo
echo `expr "$Stext" : '.*World'`      # 11

хотя оба ищут слово,Я думаю, оба не возвращают то, что они находят. Почему?

4 ответов


оба выражения эквивалентны, разница заключается в регулярном выражении, которое вы используете:

$ echo `expr "$Stext" : '^\(.[a-z]*\)'`
Hallo
$ echo `expr "$Stext" : '^.[a-z]*'`
5
$ echo `expr "$Stext" : '\(.*World\)'`
Hallo World
$ echo `expr "$Stext" : '.*World'`
11

Как вы можете видеть, скобки-это то, что имеет значение для возврата длины совпадения или самого совпадения.

вы можете найти больше примеров в Глава 10 из руководства Advanced Bash-Scripting.


можно использовать 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-му выражению в скобках.


Я сделал эту простую функцию:

match() {
    TRUE=1
    FALSE=0
    match_return=0
    echo  | grep  >/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


для быстрого поиска строк ... Один из вариантов-grep.
Если не найден, возвращает пустой, иначе это совпадение:

found=`echo $big | grep -e $short`

if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi