2012-05-18 31 views
9

Tôi muốn thay thế tất cả các cặp dấu ngoặc vuông trong một tập tin, ví dụ, [some text], với \macro{some text}, ví dụ:Làm cách nào để thay thế các dấu ngoặc vuông được ghép nối với cú pháp khác bằng sed?

This is some [text]. 
This [line] has [some more] text. 

này trở thành:

This is some \macro{text}. 
This \macro{line} has \macro{some more} text. 
  • Các cặp chỉ xảy ra trên đường dây cá nhân , không bao giờ trên nhiều dòng.
  • Đôi khi có thể có nhiều hơn một cặp trên một dòng, nhưng chúng không bao giờ được lồng nhau.
  • Nếu một khung được tìm thấy một mình trên một đường thẳng, không có cặp thì không được thay đổi.

Làm cách nào để thay thế các cặp dấu ngoặc vuông này bằng mã này?

Trả lời

6
sed -e 's/\[\([^]]*\)\]/\\macro{\1}/g' file.txt 

Điều này sẽ tìm một dấu ngoặc mở, bất kỳ số nào của các dấu ngoặc nhọn rõ ràng, sau đó là một dấu ngoặc đóng. Nhóm được chụp bởi các parens và chèn vào biểu thức thay thế.

2

Các biểu thức sau đây phù hợp với mô hình [a-z, A-Z and space] và thay thế nó bằng \macro{<whatever was between the []>}

sed -e 's/\[\([a-zA-Z ]*\)\]/\\macro{\1}/g' 

Trong các biểu hiện dưới hình thức \(... \) một nhóm trận đấu có thể được tham chiếu sau này trong thay như \1

+0

Điều này có thể đúng với dữ liệu thử nghiệm được cung cấp nhưng '[^]] *' phù hợp hơn. – potong

3

nhóm sử dụng

sed 's|\[\([^]]*\)\]|\\macro{\1}|g' file 
21

Phải mất một chút làm, nhưng ở đây:

sed -i.bkup 's/\[\([^]]*\)\]/\\macro{\1}/g' test.txt 

Hãy xem nếu tôi có thể giải thích biểu thức chính quy này:

  1. Các \[ là phù hợp với một khung vuông. Vì [ là một ký tự biểu thức chính quy thường xuyên, dấu gạch chéo ngược có nghĩa là khớp với ký tự chữ.
  2. (...) là nhóm chụp. Nó nắm bắt một phần của biểu thức chính quy mà tôi muốn. Tôi có thể có nhiều nhóm chụp và trong số sed Tôi có thể tham chiếu chúng dưới dạng \1, \2, v.v.
  3. Bên trong nhóm chụp \(...\). Tôi có [^]]*.
    1. Cú pháp [^...] có nghĩa là bất kỳ ký tự nào.
    2. [^]] có nghĩa là bất kỳ ký tự nào nhưng dấu ngoặc nhọn.
    3. * có nghĩa là không hoặc nhiều điểm trước đó. Điều đó có nghĩa là tôi đang chụp không hoặc nhiều ký tự không đóng dấu ngoặc vuông.
  4. Các \] có nghĩa là đóng khung vuông

Hãy nhìn vào dòng đây là [một số] hơn [text]

  • Trong # 1 ở trên, tôi chụp đầu tiên mở khung hình vuông ở phía trước của từ một số. Tuy nhiên, nó không nằm trong nhóm chụp. Đây là nhân vật đầu tiên tôi sẽ thay thế.
  • Tôi bây giờ bắt đầu một nhóm chụp. Tôi đang chụp theo 3.2 và 3.3 ở trên, bắt đầu bằng chữ cái s trong số một số ký tự số càng nhiều càng tốt mà không đóng dấu ngoặc vuông. Điều này có nghĩa là tôi đang khớp với [some, nhưng chỉ chụp some.
  • Trong # 4, tôi đã kết thúc nhóm chụp của mình. Tôi đã khớp với mục đích thay thế [some và bây giờ tôi đang khớp trên khung hình cuối cùng đóng. Điều đó có nghĩa là tôi đang khớp với [some]. Lưu ý rằng các biểu thức thông thường thường tham lam. Tôi sẽ giải thích dưới đây lý do tại sao điều này là quan trọng.
  • Bây giờ, tôi có thể khớp chuỗi thay thế. Điều này dễ dàng hơn nhiều. Đó là \\macro(\1). Các \1 được thay thế bởi nhóm chụp của tôi. \\ chỉ là dấu gạch chéo ngược. Do đó, tôi sẽ thay thế [some] bằng \macro{some}.

Sẽ dễ dàng hơn nhiều nếu tôi có thể được đảm bảo một tập hợp các dấu ngoặc vuông trong mỗi dòng. Sau đó, tôi có thể thực hiện việc này:

sed -i.bkup 's/\[\(.*\)\]/\\macro(\1)/g' 

Nhóm chụp hiện đang nói bất cứ điều gì giữa các dấu ngoặc vuông. Tuy nhiên, vấn đề là các biểu thức thông thường là tham lam, điều đó có nghĩa là tôi đã khớp từ s trong some tất cả các cách đến cuối cùng t trong văn bản. Chữ 'x' bên dưới hiển thị nhóm chụp. Các [] hiển thị các dấu ngoặc vuông Tôi phù hợp trên:

this is [some] more [text] 
     [xxxxxxxxxxxxxxxx] 

này đã trở thành phức tạp hơn bởi vì tôi đã phải phù hợp về nhân vật mà có ý nghĩa đặc biệt đối với biểu thức thông thường, vì vậy chúng tôi nhìn thấy rất nhiều backslashing. Thêm vào đó, tôi phải tính đến sự tham lam biểu hiện chính quy, có chuỗi tìm kiếm, không phù hợp [^]]* để khớp với bất kỳ thứ gì không phải là dấu ngoặc đóng. Thêm vào dấu ngoặc vuông trước và sau \[[^]]*\] và đừng quên nhóm chụp \(...\): \[\([^]]*\)\] Và bạn nhận được một mớ hỗn độn lớn của cụm từ thông dụng.

+0

Giải thích tốt! Tuy nhiên, thay thế phải được bao quanh bởi '\ macro {...}' – potong

+0

Sửa lỗi nhỏ ... Đã chỉnh sửa câu trả lời của tôi. Trên một màn hình nhỏ, đôi khi rất khó để thấy sự khác biệt giữa '(' và '{'. –

Các vấn đề liên quan