Cách in một dòng nếu dòng đó hoặc dòng tiếp theo không chứa một chuỗi cụ thể


8

Input.txt:

    8B0C
    remove
    8B0D
    remove
    8B0E
    remove
    8B0F
    8B10
    remove
    8B14
    remove
    8B15
    remove
    8B16
    remove
    8B17
    remove
    8AC0
    8AC1
    remove
    8AC2
    remove
    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

Sản phẩm chất lượng:

    8B0F
    8AC0
    8AE4
    8AE5

Tôi muốn in một dòng nếu dòng đó hoặc dòng tiếp theo không chứa 'remove'. Tôi đang sử dụng solaris 5.10, KSH.


@don_crissti Cảm ơn, tôi có thể đánh dấu câu hỏi này là câu trả lời nếu bạn đăng câu trả lời của bạn thay vì bình luận.
ayrton_senna 16/07/2015

Câu trả lời:


14

Với sed:

sed '$!N;/remove/!P;D' infile

Thao tác này kéo Ndòng ext vào không gian mẫu (nếu không phải !trên $dòng la t) và kiểm tra xem không gian mẫu có khớp không remove. Nếu nó không (có nghĩa là không có một trong hai dòng trong không gian mẫu có chứa chuỗi remove), nó Pgợi ý đến \nký tự ewline đầu tiên (nghĩa là nó in dòng đầu tiên). Sau đó, nó Dchạy đến \nký tự ewline đầu tiên và khởi động lại chu kỳ. Bằng cách này, không bao giờ có nhiều hơn hai dòng trong không gian mẫu.


Đây có thể là dễ dàng hơn để hiểu được N, P, Dchu kỳ nếu bạn thêm ltrước và sau khi Nnhìn vào không gian mẫu:

sed 'l;$!N;l;/remove/!P;D' infile

vì vậy, chỉ sử dụng sáu dòng cuối cùng từ ví dụ của bạn:

    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

lệnh cuối cùng xuất ra:

    8AC3 $
    8AC3 \ n xóa $
    xóa $
    xóa \ n 8AE4 $
    8AE4 $
    8AE4 \ n 8AE5 $
    8AE4
    8AE5 $
    8AE5 \ n 8AE6 $
    8AE5
    8AE6 $
    8AE6 \ n xóa $
    xóa $
    xóa $

Đây là một lời giải thích ngắn:

cmd đầu ra cmd
l     8AC3$                  N # read in the next line
l     8AC3\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                N # read in the next line
l     remove\n    8AE4$      D # delete up to \n (pattern space matches so no P)
l     8AE4$                  N # read in the next line
l     8AE4\n    8AE5$        # pattern space doesn't match so print up to \n
P     8AE4                   D # delete up to \n
l     8AE5$                  N # read in the next line
l     8AE5\n    8AE6$        # pattern space doesn't match so print up to \n
P     8AE5                   D # delete up to \n 
l     8AE6$                  N # read in the next line
l     8AE6\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                # last line so no N 
l     remove$                D # delete (pattern space matches so no P)

5
awk '
    !/remove/ && NR > 1 && prev !~ /remove/ {print prev} 
    {prev = $0} 
    END {if (!/remove/) print}
' Input.txt 

2
gawk 'BEGIN{ RS="remove\n"; ORS="" }
      RT{ print gensub("[^\n]*\n$","","") }; !RT{ print }' file

Phương pháp trên không đọc từng dòng Bản ghi , thay vào đó, nó đọc Bản ghi nhiều dòng từ một Dấu tách bản ghi (RS) sang dòng tiếp theo (hoặc cuối tệp) - chính RSlà dòng "xóa" (bao gồm cả dòng "loại bỏ" dấu vết `\ n).

Các !RTxét nghiệm cần thiết cho khi dòng cuối cùng không phải là một RSdòng.
RT, một gawk-ism , là văn bản thực tế của bản ghi hiện tại RS.
gensubcũng là một gawk-ism .

Nếu bạn cần kiểm tra một dòng đánh dấu khớp với "loại bỏ" bất cứ nơi nào trong dòng, so với một dòng bằng "loại bỏ", thì chỉ cần thay đổi Dấu tách bản ghi thành:

`RS="[^\n]*remove[^\n]*\n"`  

Đầu ra:

8B0F
8AC0
8AE4
8AE5
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.