2011-12-22 30 views
36

Tôi đã sau chuỗi:grep: nhóm chụp

{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234} 

và tôi cần để có được giá trị của "phiên bản chương trình", mà là 1234 trong ví dụ này.

Tôi đã thử

grep -Eo "\"scheme_version\":(\w*)" 

tuy nhiên nó sẽ trả về

"scheme_version":1234 

Làm thế nào tôi có thể làm cho nó? Tôi biết tôi có thể thêm sed cuộc gọi, nhưng tôi muốn làm điều đó với grep đơn.

+0

Tôi không nghĩ rằng nó có thể chỉ với 'grep'. Một vài năm trước, tôi đã làm rất nhiều với thao tác chuỗi, thường đường ống greps để các công cụ như 'sed', hoặc 'cắt'. Tôi đề nghị bạn học 'piping' và lệnh 'cut'. –

+0

Tôi không sử dụng grep thường xuyên, nhưng có lẽ bạn có thể sử dụng một biểu thức nhìn phía sau, như được nêu trong câu trả lời được chấp nhận trong http://stackoverflow.com/questions/1247812/im-stuck-in-trying-to- grep-anything-just-after-name. –

+1

Sử dụng [jq] (https://stedolan.github.io/jq) –

Trả lời

37

Điều này có thể làm việc cho bạn:

echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | 
sed -n 's/.*"scheme_version":\([^}]*\)}/\1/p' 
1234 

Xin lỗi nó không grep, vì vậy hãy bỏ qua giải pháp này nếu bạn muốn.

Hoặc gắn bó với grep và thêm:

grep -Eo "\"scheme_version\":(\w*)"| cut -d: -f2 
+0

Có vẻ như đây là lựa chọn tốt nhất có sẵn cho tôi. – lstipakov

52

Bạn sẽ cần phải sử dụng một cái nhìn đằng sau khẳng định để nó không được bao gồm trong trận đấu:

grep -Po '(?<=scheme_version":)[0-9]+'

+0

Hmm Tôi nhận grep: Hỗ trợ tùy chọn -P không được biên dịch thành mã nhị phân này --disable-perl-regexp – lstipakov

+4

@Stipa Nếu không PCRE hỗ trợ bạn không thể làm những gì bạn muốn với grep vì nó không hỗ trợ backreferences tức là '\ 1' – SiegeX

+1

+1' -P' perl tuyệt vời! – kev

30

tôi sẽ khuyên bạn nên sử dụng jq cho công việc. jq là một bộ xử lý JSON dòng lệnh.

$ cat tmp 
{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234} 

$ cat tmp | jq .scheme_version 
1234 
+1

Tôi đã hoạt động thế nào trong cuộc sống mà không biết về jq. Wow. Cảm ơn! – brian

-1

Bạn có thể làm điều này:

$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | awk -F ':' '{print $4}' | tr -d '}' 
+1

Trong khi khối mã này có thể trả lời câu hỏi của OP, câu trả lời này sẽ hữu ích hơn nhiều nếu bạn giải thích cách mã này khác với mã trong câu hỏi, những gì bạn đã thay đổi, tại sao bạn thay đổi nó và lý do giải quyết vấn đề mà không giới thiệu người khác. – davejal

14

Để thay thế cho phương pháp lookbehind tích cực đề nghị của SiegeX, bạn có thể thiết lập lại những điểm phù hợp để bắt đầu ngay sau khi scheme_version": với dãy thoát \K. Ví dụ:

$ grep -Po 'scheme_version":\K[0-9]+' 

này khởi động lại quá trình kết hợp sau khi đã xuất hiện scheme_version":, và có xu hướng có hiệu suất tốt hơn nhiều so với lookbehind tích cực. So sánh cả hai trên regexp101 chứng minh rằng phương thức khởi động lại kết quả đặt lại mất 37 bước và 1ms, trong khi phương pháp lookbehind tích cực mất 194 bước và 21ms.

Bạn có thể so sánh hiệu suất của mình trên regex101 và bạn có thể đọc thêm về đặt lại điểm xuất phát phù hợp trong PCRE documentation.

+0

Đây là _exactly_ những gì tôi cần; cảm ơn! – mklbtz

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