Подтвердить что ты не робот

Используя совпадение, чтобы найти подстроки в строках только с bash

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

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

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

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

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

4b9b3361

Ответ 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