In dòng khớp và dòng thứ n từ dòng phù hợp


18

Tôi đang cố gắng in dòng phù hợp và dòng thứ 4 từ dòng phù hợp (dòng chứa biểu thức tôi đang tìm kiếm).

Tôi đã sử dụng mã sau đây: sed -n 's/^[ \t]*//; /img class=\"devil_icon/,4p' input.txt

Nhưng điều này chỉ in dòng phù hợp.

Điều này chỉ in dòng thứ 4. awk 'c&&!--c;/img class=\"devil_icon/{c=4}' input.txt

Tôi chỉ cần in cả dòng phù hợp và dòng thứ 4.


Sử dụng egrep "pattern" -A4
Valentin Bajrami

@ val0x00ff đó in các dòng trong giữa quá .. đó là: nó in tiếp theo 4 dòng bắt đầu từ dòng phù hợp
Debal

bạn đang nói "Tôi đang cố in dòng phù hợp và dòng thứ 4 từ dòng phù hợp". Điều này grep -A 4 "pattern" file | sed -n '4p'thực hiện chính xác những gì bạn muốn, trừ khi tôi hiểu lầm bạn
Valentin Bajrami

không nó không. Kết quả của đoạn mã trên là </td>đó không phải là dòng thứ 4
Debal

Câu trả lời:


18

Trong awk, bạn sẽ làm như sau

awk '/pattern/{nr[NR]; nr[NR+4]}; NR in nr' file > new_file`

hoặc là

awk '/pattern/{print; nr[NR+4]; next}; NR in nr' file > new_file`

Giải trình

Giải pháp đầu tiên tìm thấy tất cả các dòng phù hợp pattern. Khi tìm thấy kết quả khớp, nó lưu số bản ghi ( NR) trong mảng nr. Nó cũng lưu trữ bản ghi thứ 4 từ NRtrong cùng một mảng. Điều này được thực hiện bởi nr[NR+4]. Mỗi bản ghi ( NR) sau đó được kiểm tra để xem nó có trong nrmảng không, nếu vậy bản ghi được in.

Giải pháp thứ hai về cơ bản hoạt động theo cùng một cách, ngoại trừ khi nó gặp patternnó, nó in dòng đó, và sau đó lưu bản ghi thứ 4 trước nó trong mảng nr, sau đó chuyển đến bản ghi tiếp theo. Sau đó, khi awkgặp bản ghi thứ 4 này, NR in nrkhối sẽ được thực thi và in bản ghi +4 này sau đó.

Thí dụ

Đây là một tệp dữ liệu ví dụ , sample.txt.

$ cat sample.txt 
1
2
3
4 blah
5
6
7
8
9
10 blah
11
12
13
14
15
16

Sử dụng giải pháp thứ 1:

$ awk '/blah/{nr[NR]; nr[NR+4]}; NR in nr' sample.txt 
4 blah
8
10 blah
14

Sử dụng giải pháp thứ 2:

$ awk '/blah/{print; nr[NR+4]; next}; NR in nr' sample.txt 
4 blah
8
10 blah
14

3
Đẹp, +1. Bạn đang sử dụng rất nhiều awkphím tắt ở đây, bạn có thể thêm một lời giải thích ngắn không (những thứ như in được ngụ ý trong awk và các mảng đó có liên quan, v.v.)?
terdon

đồng ý với @terdon xin vui lòng bạn có thể giải thích mã một chút.
Debal

@slm Cảm ơn bạn đã cải thiện và cung cấp câu trả lời đầy đủ!
Valentin Bajrami

1
Cảm ơn câu trả lời, tôi cũng học được điều gì đó mới mẻ với nó.
slm

4
sed -n 's/^[ \t]*/; /img class=\"devil_icon/,+4 { 3,5d ; p }' input.txt

Tôi chỉ đơn giản là thêm một dòng xóa thích hợp, trước khi in { 3,5d ; p }.


biểu thức của bạn tạo ra lỗi: sed: -e expression #1, char 18: unknown option to s'`
khoáng sản

4

Bạn có thể thử -Atùy chọn với grep, trong đó chỉ định có bao nhiêu dòng sau khi dòng phù hợp sẽ được in. Kết hợp điều này với sed, và bạn sẽ nhận được các dòng yêu cầu.

grep -A 4 pattern input.txt | sed -e '2,4d'

Sử dụng sed, chúng tôi xóa từ dòng thứ hai cho đến dòng thứ tư.


3
Điều này giả định một trận đấu duy nhất patterntrong tập tin.
terdon

2

Đây là một cách trong Perl có thể xử lý một số dòng phù hợp tùy ý:

perl -ne '/pattern/ && do{$c=$.; print}; $.==$c+4 && print' file > new_file`

Trong Perl. biến đặc biệt $.là số dòng hiện tại. Vì vậy, mỗi lần tôi tìm thấy một dòng khớp pattern, tôi sẽ in nó và lưu số dòng của nó là $c. Sau đó tôi in lại khi số dòng hiện tại nhiều hơn 4 số được in trước đó.


0
awk 'c&&!--c;/img class=\"devil_icon/{c=4};/img class=\"devil_icon/' input.txt

Về cơ bản bạn đang tìm và thay thế. Bạn có thể thêm chỉ cần tìm vào cùng một lệnh và nó sẽ in cả hai thứ đó :)

awk 'c&&!--c;/pattern/{c=4};/pattern/' input.txt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.