2012-02-13 26 views
10

Tôi đã cố gắng để trích xuất một số như đưa ra dưới đây nhưng không được in trên màn hình:sed nhóm giải nén các chữ số

echo "This is an example: 65 apples" | sed -n 's/.*\([0-9]*\) apples/\1/p' 

Tuy nhiên, tôi nhận được '65', nếu cả hai chữ số được kết hợp riêng biệt như đưa ra dưới đây:

echo "This is an example: 65 apples" | sed -n 's/.*\([0-9][0-9]\) apples/\1/p' 
65 

Làm cách nào tôi có thể khớp số để không biết số chữ số trong một số được trích xuất ví dụ nó có thể là 2344 thay cho 65?

Trả lời

14
$ echo "This is an example: 65 apples" | sed -r 's/^[^0-9]*([0-9]+).*/\1/' 
65 
+2

+1, nhưng hãy cẩn thận rằng không phải tất cả sed hỗ trợ -r và do đó không thể sử dụng '+ 'sửa đổi và phải thoát khỏi các parens. –

+1

Tại sao một regex như '[([0-9] *) táo]' (http://sprunge.us/feGV) không hoạt động trong sed? Nó hoạt động tốt trong python. –

+0

vì vậy ...^[^ 0-9] * tương ứng với mọi thứ không phải chữ số ở đầu dòng. [0-9] + ít nhất một chữ số trở lên, phải không? – baltoro

1

Điều bạn đang thấy là hành vi tham lam của regex. Trong ví dụ đầu tiên của bạn, .* gobbles lên tất cả các chữ số. Một cái gì đó như thế này:

echo "This is an example: 65144 apples" | sed -n 's/[^0-9]*\([0-9]\+\) apples/\1/p' 
65144 

Bằng cách này, bạn không thể khớp với bất kỳ chữ số nào trong bit đầu tiên. Một số phương ngữ regex có một cách để yêu cầu kết hợp không tham lam, nhưng tôi không tin rằng sed có một.

3

Đó là vì .* đầu tiên của bạn là tham lam, và [0-9]* của bạn cho phép 0 hoặc nhiều chữ số. Do đó, số .* tăng lên nhiều nhất có thể (bao gồm cả các chữ số) và [0-9]* không khớp với nội dung nào.

Bạn có thể làm:

echo "This is an example: 65 apples" | sed -n 's/.*\b\([0-9]\+\) apples/\1/p' 

nơi tôi buộc [0-9] để phù hợp với ít nhất một chữ số, và cũng đã thêm một ranh giới từ trước khi các chữ số như vậy toàn bộ số là lần xuất hiện.

Tuy nhiên, nó dễ dàng hơn để sử dụng grep, nơi bạn có phù hợp với chỉ số:

echo "This is an example: 65 apples" | grep -P -o '[0-9]+(?= +apples)' 

Các -P có nghĩa là "perl regex" (vì vậy tôi không phải lo lắng về việc thoát dấu '+').

-o có nghĩa là "chỉ in các trận đấu".

(?= +apples) có nghĩa là khớp các chữ số theo sau là từ táo.

+0

Tôi nghĩ sed không xác định được từ định danh '?' Không tham lam. [Xem này] (http://stackoverflow.com/a/1103177/167814). –

+0

ahh, tôi hiểu rồi. cổ vũ. –

+0

ví dụ đầu tiên không hoạt động –

0
echo "This is an example: 65 apples" | ssed -nR -e 's/.*?\b([0-9]*) apples/\1/p' 

Tuy nhiên, bạn sẽ cần super-sed để tính năng này hoạt động. Các -R cho phép regl perl.

1

Một cách đơn giản để trích xuất tất cả các số từ một chuỗi

echo "1213 test 456 test 789" | grep -P -o "\d+" 

Và kết quả:

1213 
456 
789