Bagaimana cara menghapus karakter duplikat?

18

Jika saya memiliki garis sebagai:

Thhiisss iisss mmyyy nameeee

Saya ingin mencetak ini sebagai:

This is my name

Apa perintah unix untuk ini?

krishna
sumber
Bisakah Anda memberikan lebih banyak konteks tentang asal usul duplikasi dan output yang diinginkan? Bagaimana jika "Mmyyy nameee iisss Jesssssiiieee"?
Paulo Almeida

Jawaban:

24

Dengan tr:

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

Penjelasan: -sberalih dari tr"meremas" karakter berulang. Seperti yang ditunjukkan, sakelar dapat digunakan dengan serangkaian karakter: ahingga z.

mkc
sumber
2
beberapa penjelasan untuk perintah ini mungkin bermanfaat bagi pembaca di masa mendatang.
Geek
8

Pada sistem GNU Anda harus menggunakan sedatau serupa jika lokal Anda menggunakan karakter multibyte ( seperti yang disarankan jimmij ) karena GNU trhanya dapat mereferensikan karakter per byte. Di lokal ASCII Anda dapat menghapus semua duplikat dengan tr:

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

Begitu...

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

... mencetak ...

This is my name

Anda juga dapat melakukannya secara selektif dengan merujuk target Anda berdasarkan rentang:

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

...atau...

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

... yang berfungsi menjadi hal yang sama, dan yang keduanya mencetak:

Thhiisss iisss mmyyy nameeee

... atau penggunaan [:punct:], [:digit:], [:lower:], [:alpha:]atau apa pun yang Anda inginkan. Anda juga dapat meniadakan pilihan -cdengan ...

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

... mencetak ...

TTTThis is my name
mikeserv
sumber
7

Satu cara dengan sed:

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

atau bahkan lebih sederhana:

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

(Terima kasih Costas dan mikeserv untuk komentar).

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

Coba tr:

echo "Thhiisss iisss mmyyy nameeee" | tr -s 'hismye'
heemayl
sumber