Sırayı korurken bitişik yinelenen satırları kaldırın


11

Her biri birkaç kez yinelenen adları olan bir sütun içeren bir dosya var. Aynı addaki diğer tekrarları, aynı adın diğer tekrarlarına bitişik tutarken, her bir tekrarı yoğunlaştırmak istiyorum.

Örneğin, sol tarafı sağ tarafa çevirmek istiyorum:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

Bu benim kullandığım şey: perl -ne 'print if ++$k{$_}==1' file.txt > file2.txt Ancak, bu yöntem sadece bir temsilci soldan tutar (yani Golb1 ve Akna tekrar edilmez).

Bitişik olmayan birden çok blokta yinelenen adları korurken, her blok için benzersiz adları tutmanın bir yolu var mı?

Yanıtlar:


23

uniq bunu sizin için yapacak:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna

2
vay bu utanç verici kolay oldu! Teşekkürler!
Yaş87

@ Age87 Unix harika! Bu yalnızca yinelenenlerin bitişik olmasını beklediğinizden (veya bitişik olmayanları kaldırmak istemediğinizden) çalışır. Normalde, tavsiye kullanmaktırsort | uniq
jpaugh

1
Veya daha özlü bir şekilde, sort -u(:
DopeGhoti

9

Awk çözüm:

awk '$1 != name{ print }{ name = $1 }' file.txt

Çıktı:

Golgb1
Akna
Spata20
Golgb1
Akna

6

Bunu deneyin - önceki satırı kaydedin ve geçerli satırla karşılaştırın

$ perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

Siz de etiketlediniz uniq- denediniz mi?

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

1

Sed ile aşağıdaki gibi yapılabilir:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

Burada desen alanında herhangi bir zamanda 2 satır var. Aralarındaki karşılaştırma başarısız olduğunda, ilkini yazdırır ve önden keseriz ve geri gider ve bir sonraki satırı desen alanına ekleriz. Durulayın ... Tekrar

Yararlanma Perl slurp modunda biz regex sizin için karşılaştırma yapar hangi uygulandığı bir uzun dize olarak tüm dosyayı davranın.

perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file

0

Rakesh Sharma'nın sed çözümü hakkında soru.

Ne gibi bir giriş dosyanız varsa:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

Ve bir çıktı dosyasının olmasını istiyorsunuz:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

Eksik olduğuna dikkat edin:

-126.118 48.216

İstediğim komutun çözümünüze benzediğini biliyorum:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

Her iki sütunu da yazdırmak için doğru şekilde değiştiremez ve yalnızca bu özel şekilde sütun 2 değerleriyle sıralanabilir. Herhangi bir ipucu?


sed -e '$!N' -e '/.*\.\([0-9]*\)\n.*\.\1$/!{P;D;}' -e 's/\n.*//;s/^/\n/;D' sonraki yinelenen öğeleri siler. Not: Bu gerektirir GNU sed. İçin POSIXdavranış, bu küçük değişimleri ihtiyacı vardır.
Rakesh Sharma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.