2012-03-07 29 views
36

Mặc dù tôi gần như chắc chắn điều này đã được đề cập đến, nhưng dường như tôi không thể tìm thấy bất kỳ điều gì cụ thể cho điều này. Khi tôi tiếp tục hành trình học bash, tôi tiếp tục tìm kiếm các phần mà tôi đang bối rối là tại sao mọi thứ xảy ra theo cách họ làm.Sử dụng kết quả phù hợp để tìm chuỗi chỉ bằng bash

Tìm kiếm và thay thế hoặc chỉ phù hợp với chuỗi con trong chuỗi rất có thể là một trong những điều đầu tiên bạn làm khi viết tập lệnh. Tuy nhiên, cố gắng để dính vào một ngôn ngữ duy nhất hoặc tập hợp các công cụ là khó khăn để làm trong bash, như bạn có thể giải quyết vấn đề nhất trong nhiều cách. Tôi đang cố hết sức để ở mức thấp nhất có thể với bash. Tôi đã gặp rắc rối khi tôi cần ai đó giải thích cho tôi.

Làm chuỗi con tìm kiếm trong bash khớp với kết quả khác nhau tùy thuộc vào biểu thức chính quy tôi sử dụng và tôi không chắc chắn lý do.

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

Mặc dù cả hai tìm kiếm cho một từ, Tôi nghĩ, cả hai không gửi lại những gì họ thấy. Tại sao?

Trả lời

23

Cả hai biểu thức là tương đương, sự khác biệt là biểu thức chính quy bạn sử dụng:

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

Như bạn thấy, ngoặc là những gì làm cho sự khác biệt cho một trong hai trở lại chiều dài của trận đấu hoặc trận đấu riêng của mình.

Bạn có thể tìm thêm ví dụ trong Chapter 10 của Hướng dẫn tạo kịch bản lệnh nâng cao.

+0

Cảm ơn @jcollado lời giải thích đơn giản :) Tôi đã sử dụng các tài liệu mà bạn cung cấp, nhưng bằng cách nào đó đã không có được điều này ngoặc chức năng. Hướng dẫn Bash-Scripting không quá dễ tiêu hóa. –

+1

Vì câu hỏi này là về [tag: bash], thích dùng * builtin * regex như [@kev đề xuất] (http://stackoverflow.com/a/9602260/1765658) thay vì * fork to '/ usr/bin/expr' *! –

49

Bạn có thể sử dụng biến BASH_REMATCH trong bash để có được chuỗi lần xuất hiện:

$ Stext="Hallo World" 
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH 
Hallo 
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]} 
Hallo 

chuỗi con phù hợp bởi subexpressions ngoặc trong biểu thức chính quy được lưu trong biến mảng BASH_REMATCH. Phần tử BASH_REMATCH có chỉ mục 0 là phần của chuỗi khớp với toàn bộ biểu thức chính quy. Phần tử BASH_REMATCH với chỉ mục n là phần của chuỗi khớp với biểu thức con thứ hai được ngoặc đơn.

+0

... và '[[" Hello world "= ~^[^ \] *]] && echo $ {# BASH_REMATCH}' -> '5' ... –

0

tôi đã thực hiện chức năng đơn giản này:

match() { 
    TRUE=1 
    FALSE=0 
    match_return=0 
    echo $1 | grep $2 >/dev/null 
    [ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE 
} 

Cách sử dụng:

match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope" 

toàn bộ mã: https://gist.github.com/TeeBSD/5121b3711fad40a09455

+0

bài đăng này không có liên quan thực sự với Câu hỏi hoặc câu trả lời. –

0

Đối với tìm kiếm chuỗi nhanh chóng ... Một lựa chọn là grep.
Nếu không tìm thấy, trả về rỗng, ngược lại nó là một trận đấu:

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

if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi 
Các vấn đề liên quan