Làm cách nào tôi có thể xóa tất cả văn bản giữa các dấu ngoặc nhọn trong tệp văn bản nhiều dòng?


10

Thí dụ:

This is {
the multiline
text file }
that wants
{ to be
changed
} anyway.

Nên trở thành:

This is 
that wants
 anyway.

Tôi đã tìm thấy một số chủ đề tương tự trong diễn đàn, nhưng chúng dường như không hoạt động với dấu ngoặc nhọn nhiều dòng.

Nếu có thể, tôi thích một số phương pháp một dòng, như các giải pháp dựa trên grep, sed, awk ... vv

EDIT: Các giải pháp có vẻ ổn, nhưng tôi nhận thấy rằng các tệp gốc của tôi bao gồm các dấu ngoặc nhọn lồng nhau. Vì vậy, tôi đang mở một câu hỏi mới. Cảm ơn tất cả mọi người: Làm cách nào tôi có thể xóa tất cả văn bản giữa các dấu ngoặc nhọn lồng nhau trong tệp văn bản nhiều dòng?


1
Hãy thử điều nàysed '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

Câu trả lời:


10
$ sed ':again;$!N;$!b again; s/{[^}]*}//g' file
This is 
that wants
 anyway.

Giải trình:

  • :again;$!N;$!b again;

    Điều này đọc toàn bộ tập tin vào không gian mẫu.

    :againlà một nhãn hiệu Nđọc trong dòng tiếp theo. $!b againcác chi nhánh trở lại againnhãn với điều kiện đây không phải là dòng cuối cùng.

  • s/{[^}]*}//g

    Điều này loại bỏ tất cả các biểu thức trong niềng răng.

Trên Mac OSX, hãy thử:

sed -e ':again' -e N -e '$!b again' -e 's/{[^}]*}//g' file

Niềng răng lồng nhau

Chúng ta hãy coi đây là một tệp thử nghiệm với rất nhiều dấu ngoặc nhọn:

a{b{c}d}e
1{2
}3{
}
5

Đây là một sửa đổi để xử lý niềng răng lồng nhau:

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file2
ae
13
5

Giải trình:

  • :again;$!N;$!b again

    Điều này giống như trước đây: nó đọc trong toàn bộ tập tin.

  • :b

    Điều này xác định một nhãn b.

  • s/{[^{}]*}//g

    Điều này loại bỏ văn bản trong dấu ngoặc nhọn miễn là văn bản không chứa dấu ngoặc trong.

  • t b

    Nếu lệnh thay thế ở trên dẫn đến thay đổi, hãy quay lại nhãn b. Theo cách này, lệnh thay thế được lặp lại cho đến khi tất cả các nhóm nẹp được loại bỏ.


Câu trả lời của bạn dường như là hoàn hảo. Miễn là câu hỏi mới tôi vừa mở (đọc câu hỏi gốc EDIT) không hoàn toàn giống nhau, tôi nghĩ bạn cũng nên trả lời nó. Nó sẽ ổn với các quy tắc diễn đàn?
Sopalajo de Arrierez

@ John1024, bạn có thể chuyển bản chỉnh sửa của mình sang đây vì OP đã đăng một câu hỏi mới liên quan đến điều tương tự.
Ramesh

1
ĐỒNG Ý. Tôi đã sao chép nó ở đó và sửa đổi nó để sử dụng văn bản mẫu trong câu hỏi mới.
John1024

5

Perl:

perl -0777 -pe 's/{.*?}//sg' file

Nếu bạn muốn chỉnh sửa tại chỗ

perl -0777 -i -pe 's/{.*?}//sg' file

Nó đọc tệp dưới dạng một chuỗi và thực hiện tìm kiếm và thay thế toàn cầu.

Điều này sẽ xử lý giằng lồng:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'

Cảm ơn bạn, điều này rất hữu ích! Điều này đã giúp tôi giải quyết một vấn đề với một xây dựng kịch bản để thay thế các nội dung của một hàm trong vòng vài phút vs đấu tranh với sed với ah..em, nhiều thời gian hơn thì tôi sẽ thừa nhận (hours..cough..cough)
AndrewD

4

Trầm tích

sed '/{/{:1;N;s/{.*}//;T1}' multiline.file

bắt đầu từ dòng với {và lấy dòng tiếp theo ( N) cho đến khi thay thế ( {}) có thể được thực hiện ( Tcó nghĩa là quay trở lại đánh dấu được thực hiện :nếu thay thế không được thực hiện)

Một chút sửa đổi là đúng nếu nhiều curle lợ trong một dòng

sed ':1; s/{[^}]*}// ; /{/ { /}/!N ; b1 }' multiline.file

Xóa tất cả các ký hiệu trong ngoặc ( [^}]bằng mọi ký hiệu ngoại trừright bracket để sedkhông tham lam) và nếu trong dòng vẫn còn left bracked- quay lại bắt đầu với dòng tiếp theo được thêm nếu không có right bracket.

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.