Tìm kiếm và thay thế đa dòng trong Linux


1

Đã thử điều này với vim, nhưng mở cho các ý tưởng / đề xuất khác.

Muốn thực hiện tìm kiếm và thay thế trong một tệp có 12000 dòng.

Cụ thể, nếu sự xuất hiện của "^ SetFontSize 28" tồn tại sau định nghĩa "^ Ẩn" và trước "^ Ẩn" hoặc "Hiển thị" tiếp theo, hãy thay đổi 28 thành 18. Ví dụ bên dưới.

Đây là một đoạn trích từ tệp gốc.

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    LinkedSockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 28

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    Sockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 28

Show # Gear - Endgame
    ItemLevel >= 83
    Rarity = Normal
    Sockets < 3
    BaseType "Tiger Hook"
    SetTextColor 240 240 240 # Normal Item Highlight
    SetBackgroundColor 70 70 70
    SetFontSize 28

Kết quả cuối cùng cho khối "Ẩn" đầu tiên sẽ trông như thế này:

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    LinkedSockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 18

Thay thế SetFontSize 28 thành SetFontSize 18, nhưng chỉ khi nó xuất hiện trong khối "^ Hide".

Regex khó chịu tôi đã thử trong vim: :%s/^Hide\(.*\)SetFontSize 28$/Hide\1SetFontSize 18/g

Nhưng đã nói mẫu không tìm thấy. Vui lòng cho tôi biết nếu có bất kỳ thông tin bổ sung nào được yêu cầu hoặc nếu yêu cầu của tôi không rõ ràng.

Câu trả lời:


1

Chỉ cần sửa hai:

  • Trong regrec của Vim, . không bao gồm các dòng mới. Có lẽ có một số cách tốt hơn, nhưng tôi thường chỉ làm (.|[\n]) khi tôi cần điều đó
  • * là tham lam, nhưng bạn muốn kết hợp không tham lam ở đây. {-} không lừa

Và một điều nữa, đó là sở thích cá nhân của tôi, vì vậy hãy xem nó có giá trị gì: Tôi đã rất khó nhớ được nhân vật ma thuật nào trong regrec của Vim, và cái gì không; vì vậy tôi đã kết thúc việc sử dụng \v ở phần đầu của mẫu, sao cho tất cả các ký tự ASCII ngoại trừ '0'-'9', 'a'-'z', 'A'-'Z''_' có một ý nghĩa đặc biệt.

Tất cả trong tất cả:

%s/\v^Hide((.|[\n]){-})SetFontSize 28/Hide\1SetFontSize 18/g


Điều này hoạt động, nhưng nó chảy máu vào khối tiếp theo. Ví dụ: nếu bạn xem đoạn trích trong bản gốc, có 3 khối. Tôi muốn chỉnh sửa 2 khối có nhãn "Ẩn" nhưng để khối "Hiển thị" không được sửa đổi. Vì một số lý do, mọi khối "Hiển thị" sau khối "Ẩn" cũng có SetFontSize thay đổi từ 28 thành 18. Thay đổi chỉ nên xảy ra trên các khối "Ẩn". Ý tưởng?
Guy

Ok, vì vậy tôi vừa thử đề xuất của bạn trong đoạn trích và nó hoạt động hoàn hảo, khiến khối "Hiển thị" không được chỉnh sửa. Nhưng khi các khối Hiển thị / Ẩn bổ sung được thêm vào (chỉ cần sao chép / dán các khối, nhân đôi nó lên 6 hoặc 12, v.v.), đó là hành vi được mô tả ở trên. Chỉnh sửa khối Ẩn, nhưng cũng là khối Hiển thị ngay bên dưới khối Ẩn.
Guy

Khi tôi sao chép, dán đoạn mã gốc và thêm các khối Hiển thị / Ẩn khác ,: đặt hlsearch vào, nó làm nổi bật các khối Ẩn chính xác bằng nửa đầu tiên của tìm / thay thế bạn cung cấp. Nhưng khi tôi sao chép / dán toàn bộ đề xuất, tất cả chúng đều được tô sáng, Hiển thị và Ẩn. Thật kỳ lạ ... Đây là tập tin tôi đang chỉnh sửa toàn bộ. Một lần nữa, chỉ muốn tất cả các khối "Ẩn" với SetFontSize 28 thay đổi thành SetFontSize 18. clbin.com/Fbr10
Guy

Cập nhật. Làm cho nó hoạt động với ... :%s/^Hide\(\(.\+\n\)\{-}.*\)SetFontSize 28/Hide\1SetFontSize 18/g
Guy

\_. giống như . nhưng phù hợp với dòng mới. Xem: :help /\_.
Heptite
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.