2013-04-17 13 views
8

Tôi cần tìm kiếm tệp cho chuỗi, xóa bất kỳ dòng nào chứa chuỗi và cũng xóa hai dòng sau bất kỳ dòng nào chứa chuỗi. Tôi đã hy vọng tôi có thể thực hiện điều này bằng cách sử dụng một cái gì đó như thế này ...Kết hợp cờ -v và cờ -A trong grep

$ grep -v -A 2 two temp.txt 
one 
five 
$ 

... nhưng tiếc là điều này không hoạt động. Có một đơn giản tôi có thể làm điều này với grep hoặc một lệnh shell?

Trả lời

5

Các công trình sau đây cả với GNU sed và với OS X.

$ sed '/two/{N;N;d;}' temp.txt 
one 
five 
  • tìm dòng phù hợp với two
  • đọc trong hai dòng hơn
  • xóa chúng
+0

Cả câu trả lời và @ JohnKugelman đều súc tích, cả hai đều hoạt động trên GNU/Linux, và không hoạt động trên OS X (không phải là một vấn đề lớn đối với tôi đối với công việc cụ thể này). Để cung cấp giải thích ngắn gọn về cú pháp, câu trả lời được chấp nhận sẽ chuyển đến bạn. Cảm ơn. –

+2

Thêm dấu chấm phẩy sau d và. Thực thi cú đúp và nó cũng hoạt động trên MacOS X. –

2

Với GNU sed:

sed '/two/,+2d' temp.txt 

Điều này sử dụng cú pháp hai địa chỉ (addr1,addr2) để đối sánh các dòng có từ hai (/two/) cộng với hai dòng sau (+2). Lệnh d xóa các dòng đó.

+0

Điều duy nhất tôi có thể nghĩ là có thể họ đang sử dụng một sed cũ hơn, không phải GNU, không có tùy chọn '+ number'. Nhưng kể từ khi nó hoạt động (và tôi không thích downvoters lái xe), đây là một cuộc bỏ phiếu để đảo ngược nó. – paxdiablo

3

Bạn có thể làm điều này với awk, theo bảng điểm sau:

pax> echo 'one 
two 
three 
four 
five' | awk '/two/ {skip=3} skip>0 {skip--;next} {print}' 

one 
five 

Nó cơ bản bắt đầu một bộ đếm của dòng để vứt bỏ (3) bất cứ khi nào nó tìm two chuỗi trên một đường thẳng. Sau đó nó ném những dòng đó đi cho đến khi bộ đếm bỏ qua đạt đến số không. Bất kỳ dòng nào không được đánh dấu để bỏ qua đều được in.

+0

Điều này có lợi thế là xử lý 'một hai ba hai ba bốn năm' →' một năm' chính xác. –

1

Dưới đây là một cách để làm điều đó với Perl:

$ perl -ne'if (/two/){$x=<>;$x=<>;}else{print}' temp.txt 
one 
five 

Các -n là một vòng lặp ngầm so với đầu vào. Nếu bạn khớp với /two/, hãy đọc hai dòng tiếp theo, nếu không, hãy in dòng bạn đang truy cập.

Vấn đề là, tuy nhiên, nếu bạn có dòng thứ ba hoặc thứ tư khớp/hai/thì bạn vẫn sẽ nhận được cùng một đầu ra. Giải pháp @ paxdiablo hoàn chỉnh hơn. Nhưng số của tôi nhiều hơn Q & D.