2013-07-30 38 views
5

Làm thế nào để dễ dàng in dòng phía trên kết quả phù hợp và bỏ qua chính kết hợp đó? grep-A, -B-o chọn không giải quyết. Có lẽ một số ma thuật awk?grep - dòng in trước, không in khớp

ví dụ:

$ cat foo.txt 
bar 
foo 
baz 
foo 

$ cat foo.txt | grep foo-SOMETHING 
bar 
baz 

Sửa

  • trong trường hợp khi dòng 2 và 3 có "foo", sau đó dòng 1 và 2 sẽ được in (mặc dù tôi không phải là rất nghiêm ngặt tại đây)

Tính năng bổ sung: xem ví dụ:

bar 
foo 
baz 
foo 
foo 

này lý tưởng nên trở

bar 
baz 
foo 
+1

Có gì sai với '-B'? –

+1

@ AdrianFrühwirth nó in dòng trước AND dòng phù hợp. – Barmar

+0

còn hai dòng liên tục thì khớp với 'foo' thì sao? in dòng đầu tiên? hoặc bỏ qua cả hai? – Kent

Trả lời

12
awk '!/foo/ { line = $0 } 
    /foo/ { print line }' foo.txt 

Mệnh đề đầu tiên tiết kiệm mỗi dòng phi foo trong một biến. Mệnh đề thứ hai in dòng được lưu gần nhất khi dòng phù hợp với foo.

này cũng làm việc (và xử lý các trường hợp bạn có hai foo dòng liên tiếp):

awk '/foo/ {print line} 
    {line = $0}' foo.txt 

Với grep bạn có thể làm:

grep -B 1 foo foo.txt | grep -vE 'foo|^--$' 

Các bộ lọc Lệnh thứ hai ra foo dòng và ngăn được in giữa các khối phù hợp.

+0

Nếu một dòng có chứa 'foo' sẽ được in khi nó được theo sau bởi một dòng phù hợp với' foo', refactor thành 'awk '/ foo/{dòng in} {line = $ 0}' foo.txt' – tripleee

+1

Không nên' awk '/ foo/{dòng in} {line = $ 0}' foo.txt' có đủ không? –

+0

@ AdrianFrühwirth: Vui lòng đăng nó như một câu trả lời, nó hoạt động tốt hơn khi đối phó với mẫu khớp lặp đi lặp lại (xem câu hỏi đã chỉnh sửa) –

2

Chỉ cần thiết lập p để mô hình bạn muốn:

$ awk '$0~p{print a}{a=$0}' p="foo" file 
bar 
baz 
foo 
1
awk '/foo/{print a}{a=$0}' your_file