2009-10-15 19 views
16

Không sử dụng bất kỳ ngôn ngữ lập trình nào. Chỉ sử dụng cụm từ thông dụng. là nó có thể?tìm các dòng trùng lặp và xóa bằng cụm từ thông dụng có tính năng thay thế

Ví dụ đầu vào >>

11 
22 
22 <-must remove 
33 
44 
44 <-must remove 
55 

Output >>

11 
22 
33 
44 
55 
+7

Cụm từ thông dụng được thực hiện bởi một số chương trình (SED, PERL, PYTHON, JAVA, một cái gì đó). "Không sử dụng bất kỳ ngôn ngữ lập trình nào" không có ý nghĩa gì cả. Chương trình nào chạy biểu thức chính quy? –

+0

Có, và bên cạnh những gì S.Lott nói, bạn phải chỉ định tốt hơn những gì bạn có nghĩa là "loại bỏ". Xóa tất cả các lần xuất hiện của các dòng trùng lặp? Hoặc loại bỏ tất cả-nhưng-một? Nếu cái sau, cái nào bạn muốn giữ lại, cái đầu tiên hay cái cuối cùng? Hay mệnh lệnh không quan trọng? – Davide

+0

Và cuối cùng, nên chạy trong một lần, hoặc cho phép nhiều đường chuyền? – Davide

Trả lời

42

Regular-expressions.info có một trang trên Deleting Duplicate Lines From a File

này về cơ bản nắm để tìm kiếm oneliner này:

^(.*)(\r?\n\1)+$ 

... Và thay thế bằng \1.
Lưu ý: Dot không phải phù hợp Newline

Giải thích:

Các caret sẽ phù hợp chỉ vào lúc bắt đầu của một dòng. Vì vậy, các công cụ regex sẽ chỉ cố gắng để phù hợp với phần còn lại của regex đó. Kết hợp dotstar chỉ khớp với toàn bộ dòng, bất kể nội dung của nó, nếu có. Các dấu ngoặc đơn lưu trữ các dòng phù hợp vào backreference đầu tiên.

Tiếp theo, chúng tôi sẽ đối sánh với dấu tách dòng. Tôi đặt question mark vào \r?\n để làm cho regex này hoạt động với cả tệp văn bản Windows (\r\n) và UNIX (\n). Vì vậy, đến thời điểm này, chúng tôi đã kết hợp một dòng và ngắt dòng sau.

Bây giờ, chúng tôi cần kiểm tra xem kết hợp này có bị trùng lặp với một bản sao của cùng một dòng hay không. Chúng tôi làm điều này chỉ đơn giản với \1. Đây là backreference đầu tiên giữ dòng mà chúng tôi đã so khớp. Các backreference sẽ phù hợp với văn bản rất giống nhau.

Nếu backreference không khớp, kết hợp regex và backreference sẽ bị loại bỏ, và động cơ regex sẽ thử lại ở đầu dòng tiếp theo. Nếu backreference thành công, thì plus symbol trong cụm từ thông dụng sẽ cố gắng khớp với các bản sao bổ sung của dòng. Cuối cùng, dollar symbol buộc động cơ regex kiểm tra xem văn bản được khớp ngược lại có phải là một dòng hoàn chỉnh hay không. Chúng tôi đã biết văn bản phù hợp bởi backreference được bắt đầu bởi một ngắt dòng (phù hợp bởi \ r? \ N). Vì vậy, bây giờ chúng tôi kiểm tra xem nó cũng được theo sau bởi một ngắt dòng hoặc nếu nó là ở phần cuối của tập tin bằng cách sử dụng dollar sign.

Toàn bộ trận đấu trở thành line\nline (hoặc line\nline\nline v.v.). Bởi vì chúng tôi đang thực hiện tìm kiếm và thay thế, dòng, các bản sao của nó và các ngắt dòng ở giữa chúng, tất cả đều bị xóa khỏi tệp. Vì chúng ta muốn giữ lại dòng ban đầu, nhưng không phải là bản sao, chúng tôi sử dụng \1 như văn bản thay thế để đưa dòng ban đầu trở lại trong.

3

Xem yêu cầu của tôi để biết thêm, tôi trả lời trong dễ dàng cách ngay bây giờ.

  1. Nếu thứ tự không quan trọng, chỉ cần một

    loại -u

    sẽ làm các trick

  2. Nếu thứ tự không thành vấn đề nhưng bạn không nhớ lại chạy nhiều thẻ (đây là cú pháp vim), bạn có thể sử dụng:

    % s/\ (. * \) \ (\ _. * \) \ (\ 1 \)/\ 2 \ 1/g

    để duy trì sự xuất hiện cuối cùng, hoặc

    % s/\ (. * \) \ (\ _. * \) \ (\ 1 \)/\ 1 \ 2/g

    để bảo tồn lần xuất hiện đầu tiên.

Nếu bạn nhớ chạy lại nhiều lần, khó hơn, vì vậy trước khi chúng tôi thực hiện điều đó, vui lòng nói như vậy trong câu hỏi!

CHỈNH SỬA: trong bản chỉnh sửa của bạn, bạn không rõ lắm, nhưng có vẻ như bạn chỉ muốn loại bỏ các dòng ADJACENT trùng lặp một lần! Vâng, đó là dễ dàng hơn nhiều!

Một đơn giản:

/(.*)\1*/\1/ 

(/\(.*\)\1*/\1/ trong vim) tức là tìm kiếm (.*)\1* và thay thế nó bằng chỉ \1 sẽ làm các trick

+0

'(. *) \ 1 *' không khớp với các dòng trùng lặp vì không có gì trong regex của bạn khớp với ngắt dòng giữa dòng và trùng lặp của nó. –

3

Trong RegexBuddy bạn có thể làm điều này như sau:

  1. Trên tab Thư viện, tải thư viện RegexBuddy.rbl nếu không được tải theo mặc định.
  2. Trong hộp tra cứu, nhập "trùng lặp"
  3. Nhấp vào nút Sử dụng để tải regex "xóa dòng trùng lặp".
  4. Trên tab GREP, chỉ định thư mục và tệp mặt nạ của các tệp bạn muốn xóa các từ khóa trùng lặp.
  5. Trong trình đơn thả xuống của nút GREP, chọn Thực thi.

Nếu bạn chỉ làm điều này trên một tệp, bạn có thể sử dụng tab Kiểm tra thay vì tab GREP. Tải tệp trên tab Kiểm tra, rồi bấm vào nút Thay thế trong thanh công cụ chính.

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