Câu hỏi grepping một chuỗi con từ một kết quả grep


Cho một tệp nhật ký, tôi thường sẽ làm một cái gì đó như thế này:

grep 'marker-1234' filter_log

Sự khác biệt trong việc sử dụng '' hoặc '' hoặc không có gì trong mẫu?

Lệnh grep ở trên sẽ mang lại hàng nghìn dòng; những gì tôi mong muốn. Trong những dòng này, thường có một đoạn dữ liệu mà tôi đang theo dõi. Đôi khi, tôi sử dụng awk để in ra các lĩnh vực tôi sau. Trong trường hợp này, định dạng nhật ký thay đổi, tôi không thể dựa vào vị trí độc quyền, chưa kể, dữ liệu được ghi thực tế có thể đẩy vị trí tiến lên.

Để làm cho điều này dễ hiểu, hãy nói dòng đăng nhập có chứa địa chỉ IP và đó là tất cả những gì tôi đã làm sau, vì vậy sau này tôi có thể sắp xếp nó để phân loại và duy nhất và nhận được một số đếm kiểm đếm.

Một ví dụ có thể là:

2010-04-08 some logged data, indetermineate chars - [marker-1234] (123.123.123.123) from: foo@bar.example.com to bar@foo.example.com [stat-xyz9876]

Lệnh grep đầu tiên sẽ cho tôi nhiều hàng nghìn dòng như trên, từ đó, tôi muốn đặt nó vào một cái gì đó, có lẽ sed, có thể kéo ra một mẫu bên trong và chỉ in mẫu.

Đối với ví dụ này, việc sử dụng địa chỉ IP sẽ đủ. Tôi đã thử. Là sed không thể hiểu [0-9] {1,3}. như một mô hình? Tôi đã phải [0-9] [0-9] [0-9]. trong đó mang lại kết quả kỳ lạ cho đến khi toàn bộ mô hình được tạo ra.

Đây không phải là một địa chỉ IP cụ thể, mẫu sẽ thay đổi, nhưng tôi có thể sử dụng nó làm mẫu học tập.

Cảm ơn tất cả.


4
2018-04-09 01:18


gốc


Điều này nghe có vẻ rất liên quan đến lập trình, ngay cả các lệnh bash đơn giản như grep và lúng túng theo ý kiến ​​của tôi tốt hơn được trả lời trên stackoverflow. - Josh K
@Josh: SU có rất nhiều chiến binh commandline linux có thể xử lý loại câu hỏi này, và nó được chào đón ở đây. nó có thể là một trong những câu hỏi đó sẽ phù hợp trên một trong hai trang web, do đó, nó thực sự lên đến người hỏi. - quack quixote
Tôi đã cho nó một số suy nghĩ, và phải trung thực, tôi không biết nơi để đăng nó. Tôi đã đi với tên của các trang web, figuring SO là tổng quát hơn, và SU là nhiều loại công cụ quản trị. Tôi thấy kịch bản shell nhanh nhất là admin liên quan. Chắc chắn, bạn nhận được vào các dự án độc quyền tcl hoặc bash lớn cho một lý do này hay lý do khác, trong trường hợp này tôi sẽ thu hẹp nó thành lập trình liên quan và đăng lên SO. Đây là một trong những liner'ish, và SU dường như là một ngôi nhà tốt. Xin lỗi nếu tôi đăng ở vị trí sai, nhưng có vẻ như một khu vực màu xám trong một số trường hợp. - user17245
@allentown: thực ra Lỗi máy chủ là nhiều công cụ quản trị hơn; Super User là nội dung của người dùng cuối hơn. (Tuy nhiên, nhưng người dùng cuối sử dụng điện.) dù sao, câu hỏi này có lẽ được chào đón trên bất kỳ SO / SF / SU nào. bạn đã chấp nhận câu trả lời, vì vậy nếu bạn hài lòng, bạn có thể gọi nó là xong. hoặc nếu bạn muốn chúng tôi có thể di chuyển nó sang SO / SF; chỉ gắn cờ cho sự chú ý của người kiểm duyệt và cho chúng tôi biết nơi gửi nó. cảm ơn! - quack quixote
@quack: Tốt thôi, tôi chỉ nghĩ rằng một câu trả lời tốt hơn có thể được tìm thấy ở đó, tuy nhiên có vẻ như nó đã được tìm thấy rồi. - Josh K


Các câu trả lời:


Tôi không biết bạn đang sử dụng hệ điều hành nào, nhưng trên FreeBSD 7.0+ grep có -o tùy chọn để chỉ trả về phần khớp với mẫu. Vì vậy, bạn có thể
grep "marker-1234" filter_log | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"

Trả về danh sách chỉ các địa chỉ IP từ 'filter_log' ...

Điều này hoạt động trên hệ thống của tôi, nhưng một lần nữa, tôi không biết phiên bản grep của bạn hỗ trợ.


7
2018-04-09 02:28



Tôi nghĩ rằng tất cả các câu trả lời ở đây là những cách học tập tuyệt vời và tiếp cận kết quả cuối cùng với cùng một câu trả lời. Tôi đặc biệt thích cái này vì nó dễ nhớ và chỉ là một chuỗi lệnh grep. Trên Mac OS X, tôi dường như có tùy chọn -o, và tất nhiên sử dụng tùy chọn -E đã khá thường xuyên. Cảm ơn bạn đã trả lời - user17245


bạn có thể làm tất cả những điều này chỉ trong một awk chỉ huy. Không cần sử dụng bất kỳ công cụ nào khác

$ awk '/marker-1234/{for(o=1;o<=NF;o++){if($o~/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)print $o }  }' file
(123.123.123.123)

3
2018-04-09 02:44



Cảm ơn, mà không làm việc, awk có thể làm tổn thương đầu của bạn một chút ở lần, nhưng tôi đang nhận được sử dụng để cho FOO .... một khía cạnh lót của công cụ nhanh chóng trong vỏ. Rất mạnh. - user17245


Bạn có thể rút ngắn giây grep một chút như thế này:

grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'

Để trả lời câu hỏi đầu tiên của bạn, dấu ngoặc kép cho phép trình bao làm những việc khác nhau như mở rộng biến, nhưng bảo vệ một số siêu ký tự cần phải được thoát. Dấu nháy đơn ngăn không cho trình bao mở rộng. Không sử dụng dấu ngoặc kép để mọi thứ mở rộng.

$ empty=""
$ text1="some words"
$ grep $empty some_file
(It seems to hang, but it's just waiting for input since it thinks "some_file" is 
the pattern and no filename was entered, so it thinks input is supposed to come
from standard input. Press Ctrl-d to end it.)
$ grep "$empty" some_file
(The whole file is shown since a null pattern matches everything.)
$ grep $text1 some_file
grep: words: No such file or directory
some_file:something
some_file:some words
(It sees the contents of the variable as two words, the first is seen as the 
pattern, the second as one file and the filename as a second file.)
$ grep "$text1" some_file
some_file:some words
(Expected results.)
$ grep '$text1' some_file
(No results. The variable isn't expanded and the file doesn't contain a
string that consists of literally those characters (a dollar sign followed
by "text1"))

Bạn có thể tìm hiểu thêm trong phần "QUOTING" của man bash


2
2018-04-09 04:16



Tuyệt vời viết lên, cảm ơn. Tôi cần phải có được một xử lý tốt hơn về điều này với regad IFS là tốt, tôi đã khá treo lên ngày hôm đó, nhưng đã quản lý để có được IFS để chơi tốt đẹp. Đó là một điều khủng khiếp khi bạn có IFS thiết lập và quên nó, tự hỏi wtf đang diễn ra trong một giờ. - user17245
Đó là một ý tưởng tốt để có thói quen luôn tiết kiệm giá trị của IFS và khôi phục nó càng sớm càng tốt: saveIFS="$IFS"; IFS=","; do_something; IFS="$saveIFS"; do_other_stuff - Dennis Williamson
1 Cuộc gọi tốt trên regex, tôi không sử dụng nó nhiều, vì vậy tôi có xu hướng là một chút không hiệu quả. - Chris S


Tra cứu xargs chỉ huy. Bạn sẽ có thể làm điều gì đó như:

grep 'marker-1234' filter_log | xargs grep "(" | cắt -c1-15

Điều này có thể không chính xác, nhưng xargs là lệnh bạn muốn sử dụng


1
2018-04-09 01:38