2012-11-03 29 views
6

Tôi đang cố gắng trả về lần xuất hiện đầu tiên của nhiều chuỗi, tức là tôi muốn chọn các dòng từ văn bản sau, trong đó xuất hiện lần đầu tiên là 1259, 3009 và 1589.Cần grep cho lần xuất hiện đầu tiên của nhiều chuỗi

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

DDWN  723 11:30 B04 

ADWN 1589 14:20 B12 

ADWN 1259 11:10 B23 

DDWN 2534 13:00 B16 

ADWN 3009 11:50 B14 

này mang lại cho tôi tất cả các trận đấu:

grep '1259\|3009\|1589' somelog.log 

Và điều này mang lại cho tôi chỉ là trận đấu đầu tiên

grep -m 1 '1259\|3009\|1589' somelog.log 

Tôi muốn trở lại như sau:

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

ADWN 1589 14:20 B12 

tôi nghĩ rằng tạo một tập tin với req giá trị uired, và sau đó looping thông qua các tập tin, đi qua mỗi số riêng lẻ vào lệnh grep sẽ cho tôi những gì tôi đang tìm kiếm, nhưng tôi đã không tìm thấy một ví dụ về điều này. Có một giải pháp đơn giản cho điều này, là một vòng lặp cách tốt nhất để xử lý này, hoặc có ví dụ này đã được trả lời ở nơi khác?

Cảm ơn trước cho ý tưởng của bạn và suggestions--

Clyde

Trả lời

4

Một cách sử dụng awk:

awk '!array[$2]++ && $2 ~ /^1259$|^3009$|^1589$/' file.txt 

Kết quả:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

chỉnh sửa:

Tôi thực sự nên có thói quen đọc toàn bộ câu hỏi trước. Tôi thấy rằng bạn đang nghĩ đến việc tạo tệp với các giá trị bạn muốn tìm lần xuất hiện đầu tiên. Đặt các tệp này vào một tệp có tên values.txt với một giá trị trên mỗi dòng. Ví dụ; đây là nội dung của values.txt:

1259 
3009 
1589 

Sau đó chạy này:

awk 'FNR==NR { array[$0]++; next } $2 in array { print; delete array[$2] }' values.txt file.txt 

Kết quả:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

1st lệnh giải thích:

Nếu cột thứ hai ($2) bằng một trong ba giá trị được liệt kê, thêm nó vào mảng nếu nó chưa có trong đó. awk in toàn bộ dòng theo mặc định.

lệnh thứ 2 giải thích:

FNR là số lượng hồ sơ liên quan đến các tập tin đầu vào hiện tại.
NR là tổng số bản ghi.

Cấu trúc FNR==NR { ... } chỉ đúng đối với tệp đầu vào đầu tiên.Vì vậy, đối với mỗi dòng trong values.txt, chúng tôi thêm toàn bộ dòng ($0) vào một mảng (tôi đã gọi nó là mảng, nhưng bạn có thể đặt cho nó một tên khác). next lực awk để đọc dòng tiếp theo trong values.txt (và bỏ qua xử lý phần còn lại của lệnh). Khi FNR==NR không còn đúng, tệp thứ hai trong danh sách đối số được đọc. Sau đó chúng ta kiểm tra cột thứ hai ($2) trong mảng, nếu nó ở trong đó, in nó và loại bỏ nó khỏi mảng. Bằng cách sử dụng delete, về cơ bản chúng tôi đặt số lượng tối đa là một.

+0

Steve - cảm ơn, đó là làm những gì tôi hỏi, nó sẽ trả về lần xuất hiện đầu tiên của mỗi giá trị. Tôi đã có một số đọc để làm trên awk, và hiểu cụ thể những gì mã đang làm –

+1

Tôi có thể thêm một lời giải thích nhanh chóng nếu bạn muốn. Hãy ở trong đó ... – Steve

+0

Tốt, tôi đánh giá cao sự giải thích - một số công cụ này có thể khá mờ đục! Tôi chắc chắn sẽ có thể đưa điều này để sử dụng tốt, cảm ơn một lần nữa! –

-1

Hãy thử điều này. Nó có thể không làm việc tùy thuộc vào phiên bản grep của bạn:

grep -m 1 -e pattern1 -e pattern2 
+0

Cảm ơn, thật không may, đoạn mã này chỉ trả về mẫu đầu tiên, mặc dù vậy. –

0

Cái này sẽ cũng vậy.

for i in $(cut -d " " -f1 somelog.log | sort -u); do LC_ALL=C fgrep -m1 "$i" somelog.log; done 
Các vấn đề liên quan