Tôi nghĩ lệnh sau sẽ hoạt động:
:%s/^\(.*\)\(\n\1\)\+$/\1/
Giải trình :
Chúng tôi sử dụng lệnh thay thế trên toàn bộ tệp để thay đổi pattern
thànhstring
:
:%s/pattern/string/
Đây pattern
là ^\(.*\)\(\n\1\)\+$
vàstring
là \1
.
pattern
có thể được chia nhỏ như thế này:
^\(subpattern1\)\(subpattern2\)\+$
^
và $
khớp tương ứng một đầu dòng và một cuối dòng.
\(
và \)
được sử dụng để gửi kèm theo subpattern1
để chúng ta có thể tham khảo nó sau bằng số đặc biệt \1
.
Chúng cũng được sử dụng để đính kèmsubpattern2
để chúng ta có thể lặp lại 1 hoặc nhiều lần với bộ định lượng \+
.
subpattern1
là .*
.
một metacharacter phù hợp với bất kỳ ký tự nào ngoại trừ dòng mới và *
là một bộ định lượng phù hợp với ký tự cuối cùng 0, 1 hoặc nhiều lần.
Vì vậy, .*
phù hợp với bất kỳ văn bản không chứa dòng mới.
subpattern2
là \n\1
\n
phù hợp với một dòng sản phẩm mới và \1
phù hợp với văn bản tương tự mà được kết hợp bên trong đầu tiên \(
,\)
mà ở đây là subpattern1
.
Vì vậy, pattern
có thể được đọc như thế này:
một dòng bắt đầu ( ^
) theo sau bởi bất kỳ văn bản nào không chứa dòng mới ( .*
) theo sau là một dòng mới ( \n
) sau đó cùng một văn bản ( \1
), hai dòng sau được lặp lại một hoặc nhiều lần ( \+
) và cuối cùng là kết thúc của dòng ( $
) .
Bất cứ nơi nào pattern
được khớp (một khối các dòng giống hệt nhau), lệnh thay thế sẽ thay thế nó string
ở đây \1
(dòng đầu tiên của khối).
Nếu bạn muốn xem khối dòng nào sẽ bị ảnh hưởng mà không thay đổi bất cứ điều gì trong tệp của mình, bạn có thể bật hlsearch
tùy chọn và thêm n
cờ thay thế ở cuối lệnh:
:%s/^\(.*\)\(\n\1\)\+$/\1/n
Để kiểm soát chi tiết hơn, bạn cũng có thể yêu cầu xác nhận trước khi thay đổi từng khối dòng bằng cách thêm c
cờ thay thế:
:%s/^\(.*\)\(\n\1\)\+$/\1/c
Để biết thêm thông tin về các lệnh đọc thay :help :s
,
cho những lá cờ thay :help s_flags
,
cho metacharacters khác nhau và quantifiers đọc :help pattern-atoms
,
và cho biểu thức thông thường trong vim đọc này .
Chỉnh sửa: Wildcard đã khắc phục sự cố trong lệnh bằng cách thêm một $
ở cuối pattern
.
Ngoài ra BloodGain có phiên bản ngắn hơn và dễ đọc hơn của cùng một lệnh.
$
trong đó, mặc dù. Nếu không, nó sẽ làm những điều bất ngờ với một dòng bắt đầu bằng văn bản giống hệt với dòng trước đó, nhưng có một số ký tự khác. Cũng lưu ý rằng lệnh cơ bản bạn đưa ra có chức năng tương đương với câu trả lời của tôi:%!uniq
, nhưng cờ đánh dấu và xác nhận là tốt.