2012-11-14 27 views
55

Tôi đang cố gắng trích thời gian từ chuỗi bằng cách sử dụng bash và tôi đang gặp khó khăn trong việc tìm ra nó.Trích xuất chuỗi con bằng cách sử dụng regexp ở dạng bash

chuỗi của tôi là như thế này:

US/Central - 10:26 PM (CST) 

Và tôi muốn trích xuất các phần 10:26.

Bất kỳ ai biết cách làm điều này chỉ với bash - không sử dụng sed, awk, v.v ...?

Giống như, trong PHP Tôi sẽ sử dụng - không phải là cách tốt nhất, nhưng nó hoạt động - một cái gì đó như:

preg_match(""(\d{2}\:\d{2}) PM \(CST\)"", "US/Central - 10:26 PM (CST)", $matches); 

Nhờ sự giúp đỡ, thậm chí nếu câu trả lời sử dụng sed hay awk

Trả lời

132

Sử dụng tinh khiết :

$ cat file.txt 
US/Central - 10:26 PM (CST) 
$ while read a b time x; do [[ $b == - ]] && echo $time; done < file.txt 

một giải pháp với bash regex:

$ [[ "US/Central - 10:26 PM (CST)" =~ -[[:space:]]*([0-9]{2}:[0-9]{2}) ]] && 
    echo ${BASH_REMATCH[1]} 

một giải pháp sử dụng grep và tìm kiếm xung quanh tiên tiến regex:

$ echo "US/Central - 10:26 PM (CST)" | grep -oP "\-\s+\K\d{2}:\d{2}" 

giải pháp khác sử dụng sed:

$ echo "US/Central - 10:26 PM (CST)" | 
    sed 's/.*\- *\([0-9]\{2\}:[0-9]\{2\}\).*/\1/' 

giải pháp khác sử dụng perl:

$ echo "US/Central - 10:26 PM (CST)" | 
    perl -lne 'print $& if /\-\s+\K\d{2}:\d{2}/' 

và người cuối cùng sử dụng awk:

$ echo "US/Central - 10:26 PM (CST)" | 
    awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}' 
+0

Cool! Bất kỳ cơ hội tôi sử dụng cũng là dấu gạch ngang "-" trong mô hình? vì grep đó trả về một số kết quả phù hợp và tôi chỉ quan tâm đến một dấu gạch ngang và sau đó là khoảng trắng và sau đó là thời gian ..... – andrux

+0

Bài chỉnh sửa cho phù hợp –

+0

Đã thêm một giải pháp khác –

15

nhanh 'n bẩn, regex-miễn phí,-vững mạnh thấp kỹ thuật Chop-Chop

string="US/Central - 10:26 PM (CST)" 
etime="${string% [AP]M*}" 
etime="${etime#* - }" 
+2

Điều đó thật kinh tởm đến nỗi tôi xấu hổ vì tôi không tự nghĩ về nó. +1 '| khu vực apm thời gian dash vùng đọc cũng hoạt động quá – Orwellophile

+0

Rất sạch sẽ và tránh các cuộc gọi đến các chương trình bên ngoài. –

46
echo "US/Central - 10:26 PM (CST)" | sed -n "s/^.*-\s*\(\S*\).*$/\1/p" 

-n  suppress printing 
s  substitute 
^.*  anything at the beginning 
-  up until the dash 
\s*  any space characters (any whitespace character) 
\(  start capture group 
\S*  any non-space characters 
\)  end capture group 
.*$  anything at the end 
\1  substitute 1st capture group for everything on line 
p  print it 
+0

Chào mừng bạn đến với StackOverflow! Xin lỗi, tôi đã vô tình gắn cờ cái này là "không-trả lời". Thật không may là không có cách nào để unflag, nhưng lá cờ đó sẽ bị từ chối bởi một người điều hành sớm. –

+0

Cảm ơn sự chào đón. Không phải lo lắng về cờ "không phải trả lời". – jgshawkey

+5

Tôi cảm thấy như thế này làm cho tôi một bậc thầy sed ngay lập tức. Một lựa chọn tốt tôi có thể tinh chỉnh là tốt hơn chín tôi không hiểu. – Noumenon

Các vấn đề liên quan