Làm thế nào để loại bỏ các ký tự trùng lặp?


18

Nếu tôi có một dòng như:

Thhiisss iisss mmyyy nameeee

Tôi muốn in cái này như:

This is my name

Lệnh unix cho việc này là gì?


Bạn có thể cung cấp thêm một số bối cảnh về nguồn gốc của các bản sao và đầu ra mong muốn? Điều gì sẽ xảy ra nếu "Mmyyy nameee iisss Jesssssiiieee"?
Paulo Almeida

Câu trả lời:


24

Với tr:

echo "Thhiisss iisss mmyyy nameeee" | tr -s 'a-z'

Giải thích: Việc -schuyển đổi tr"ép" các ký tự lặp lại. Như được hiển thị, công tắc có thể được sử dụng với một loạt các ký tự: ato z.


2
một số giải thích cho lệnh có thể hữu ích cho các độc giả trong tương lai.
Geek

8

Trên hệ thống GNU, bạn sẽ cần sử dụng sedhoặc tương tự nếu ngôn ngữ của bạn sử dụng các ký tự đa nhân ( như jimmij gợi ý ) vì GNU trchỉ có thể tham chiếu một ký tự cho mỗi byte. Trong ngôn ngữ ASCII, bạn có thể xóa tất cả các bản sao w / trlike:

LC_ALL=C tr -s '\0-\255' <input

Vì thế...

echo Thhiisss iisss mmyyy nameeee|
LC_ALL=C tr -s '\0-\255'

... bản in ...

This is my name

Bạn cũng có thể thực hiện một cách chọn lọc bằng cách tham khảo các mục tiêu của mình theo phạm vi:

echo TThhiisss iisss mmyyy nameeee|
LC_ALL=C tr -s '\101-\132'

...hoặc là...

echo TTTThhiisss iisss mmyyy nameeee|
LC_ALL=C tr -s '[:upper:]'

... cái nào cũng giống nhau và cả hai đều in:

Thhiisss iisss mmyyy nameeee

... hoặc sử dụng [:punct:], [:digit:], [:lower:], [:alpha:]hoặc bất cứ điều gì bạn muốn. Bạn cũng có thể phủ nhận lựa chọn w / -cvì vậy ...

echo 'TTTThhiisss     iisss mmyyy nameeee' |
LC_ALL=C tr -cs '[:upper:]'

... bản in ...

TTTThis is my name

7

Một cách với sed:

sed ':X;s/\(.\)\1/\1/g;tX'

hoặc thậm chí đơn giản hơn:

sed 's/\(.\)\1*/\1/g'

(cảm ơn Costasmikeerv cho ý kiến).


sed 's/\(.\)\1\+/\1/g'
Costas

3

Hãy thử tr:

echo "Thhiisss iisss mmyyy nameeee" | tr -s 'hismye'
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.