2012-10-19 12 views
13

Một câu hỏi khác cho các chuyên gia về sed.Trích xuất các số từ một chuỗi bằng cách sử dụng các biểu thức chính quy và thông thường

Tôi có một chuỗi đại diện cho một tên đường dẫn sẽ có hai số trong đó. Một ví dụ là:

./pentaray_run2/Trace_220560.dat 

tôi cần phải trích xuất các thứ hai của những con số - tức là 220560

Tôi có (với một số sự giúp đỡ từ các diễn đàn) đã có thể trích xuất tất cả các số với nhau (tức là 2.220.560) với :

sed "s/[^0-9]//g" 

hoặc trích lục chỉ số đầu tiên với:

sed -r 's|^([^.]+).*$|\1|; s|^[^0-9]*([0-9]+).*$|\1|' 

Nhưng những gì tôi afte r là số thứ hai !! Bất kỳ giúp đỡ nhiều đánh giá cao.

PS số mà tôi theo sau luôn là số thứ hai trong chuỗi.

Trả lời

12

có được không?

sed -r 's/.*_([0-9]*)\..*/\1/g' 

với ví dụ của bạn:

kent$ echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*/\1/g' 
220560 
+0

Công việc tuyệt vời là điều trị. Tôi đoán _ trong đó có nghĩa là để tìm những con số chỉ sau dấu gạch dưới? Trong trường hợp này tôi luôn luôn có thể mong đợi một gạch dưới để điều này sẽ làm việc. Mà thực tế bit của biểu hiện nào đó là nó. * _ Stackoverflow thực sự là một nguồn tài nguyên tuyệt vời - Tôi đã được khó hiểu tại đây trong nhiều giờ. Vì lợi ích bạn có nghĩ rằng có một cách để sử dụng \ 1 ở cuối - có lẽ trích xuất tất cả các con số (các chữ số tiếp giáp) làm nền và yêu cầu số thứ hai. Điều này có thể hữu ích cho tôi và những người khác trong tương lai? – Steven

6

Nếu grep được chào đón:

$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+' 
220560 

Và hơn thế nữa xách tay với Perl với cùng regex:

echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/' 
220560 

Tôi nghĩ phương pháp này là sạch & mạnh mẽ hơn so với sử dụng sed

6

Bạn có thể trích xuất các số cuối cùng với điều này:

sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/' 

Nó là dễ dàng hơn để nghĩ rằng đây ngược:

  1. Từ cuối chuỗi , đối sánh số không hoặc nhiều ký tự không phải chữ số
  2. So khớp (và chụp) một hoặc nhiều ký tự chữ số
  3. Khớp với ít nhất một phi chữ số nhân vật
  4. trận đấu tất cả các nhân vật khi bắt đầu của chuỗi

Phần 3 của trận đấu là nơi mà các "kỳ diệu" sẽ xảy ra, nhưng nó cũng hạn chế các trận đấu của bạn phải có ít nhất một tổ chức phi -digit trước số (ví dụ: bạn không thể khớp một chuỗi chỉ với một số ở đầu chuỗi, mặc dù có một cách giải quyết đơn giản là chèn một chữ số không vào đầu chuỗi).

Điều kỳ diệu là chống lại sự tham lam từ trái sang phải của .* (phần 4). Nếu không có phần 3, phần 4 sẽ tiêu thụ tất cả nó có thể, bao gồm các con số, nhưng với nó, kết hợp đảm bảo rằng nó dừng lại để cho phép ít nhất một chữ số không theo sau bởi một chữ số được tiêu thụ bởi các phần 1 và 2, cho phép số được chụp.

5

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

sed -r 's/([^0-9]*([0-9]*)){2}.*/\2/' file 

này chiết xuất số thứ hai:

sed -r 's/([^0-9]*([0-9]*)){1}.*/\2/' file 

và điều này chiết xuất đầu tiên.