Belirli bir karakter hariç bir satırdaki karakter sayısı nasıl hesaplanır?


9

Bu parça dosyası

N W N N N N N N N N N
N C N N N N N N N N N
N A N N N N N N N N N
N N N N N N N N N N N
N G N N N N N N N N N
N C N N N C N N N N N
N C C N N N N N N N N

Her satırda "N" olmayan tüm karakterlerin toplam sayısını saymak istiyorum

arzum çıktı

1
1
1
0
1
2
2

Kullanım sedşeyler yerine sen umurumda değil ve awkkalan uzunluğu saymaksed 's/N//g ; s/\s//g' file | awk '{ print length($0); }'
Rolf

Yanıtlar:


13

GNU awk çözümü:

awk -v FPAT='[^N[:space:]]' '{ print NF }' file
  • FPAT='[^N[:space:]]'- alan değerini tanımlayan desen ( Nkarakter ve boşluk hariç herhangi bir karakter )

Beklenen çıktı:

1
1
1
0
1
2
2


7

bu sayının boşluk karakteri dışındaki her satır için gerekli olduğunu varsayarsak ve N

$ perl -lne 'print tr/N //c' ip.txt 
1
1
1
0
1
2
2
  • dönüş değeri trkaç karakterin değiştirildiğidir
  • c verilen karakter kümesini tamamlamak
  • Kullanımına dikkat -lseçeneği, kapalı-by-one önlemek için hata girişi hattından satır karakteri şeritler ve ayrıca baskı deyimi için yeni satır karakteri ekler


Daha genel bir çözüm

perl -lane 'print scalar grep {$_ ne "N"} @F' ip.txt 
  • -agiriş satırını otomatik olarak @Fdiziye kaydedilen beyaz boşluklara bölme seçeneği
  • grep {$_ ne "N"} @F@Fdizeyle eşleşmeyen tüm öğelerin dizisini döndürürN
    • normal ifade eşdeğeri grep {!/^N$/} @F
  • kullanımı scalardizinin eleman sayısını verecektir

6

Alternatif awk çözümü:

awk '{ print gsub(/[^N[:space:]]/,"") }' file
  • gsub(...)- gsub()İşlev, yapılan değişiklik sayısını döndürür.

Çıktı:

1
1
1
0
1
2
2

6

Başka bir awkyaklaşım ( boş satırlar için -1 döndürür ).

awk -F'[^N ]' '$0=NF-1""' infile

Ya da karmaşık olarak, boş satırlarda -1 , yalnızca beyaz alanlarda (Sekmeler / Alanlar) 0 döndürür .

awk -F'[^N \t]+' '$0=NF-1""' infile

-1boş satırlar için yazdıracaktır ... ancak daha sonra yalnızca N / boşluk ve boş satırdan oluşan satırı ayırt etmek istenebilir ...
Sundeep

1
@Sundeep Evet, doğru. ayrıca satırların yalnızca 0 olarak belirtmek için Sekmeler veya Alanlar içerdiğini de güncelleyin
αғsнιη

5
  1. trve POSIX kabuk betiği:

    tr -d 'N ' < file | while read x ; do echo ${#x} ; done
    
  2. bash,, kshve zsh:

    while read x ; do x="${x//[ N]}" ; echo ${#x} ; done < file
    

1
awk '{print length()}'Yavaş kabuk döngü önlemek için kullanabilirsiniz .. ama sonra biri awk kendisi ile her şeyi yapabilir ...
Sundeep

(@Sundeep, O, doğru ise ikisi de aynı anda başlatılır) olduğu, awkdöngüye olduğunu hızlı kabuk döngü daha. Ancak kabuk her zaman hafızadadır ve awkolmayabilir - awkzaten yüklenmediğinde veya takas edilmediğinde, yükleme yükü ( kayıp zaman ), çalıştırma avantajından daha büyük olabilir awk- özellikle küçük bir döngü. Bu gibi durumlarda ( yani bu durumda) daha yavaşawk olabilir .
agc


1
@Sundeep, ben bunu endişe. Bir süre önce disketten kaçabilen disket tabanlı Linux dağıtımlarını birkaç metre koçta kullanıyordum. awkBir kabuk komut dosyasında gereksiz yere kullanmak , böyle bir sistemin dört ayak üzerinde sürmesini sağlayabilir. Genel olarak: aynı gecikme süresi sınırlı bellenimdeki sistemlere veya ağır yük altındaki sistemlere uygulanır.
agc

1

Kısa bir kombinasyonu trve awk:

$ tr -d ' N' <file.in | awk '{ print length }'
1
1
1
0
1
2
2

Bu, giriş dosyasındaki tüm N'leri siler ve awkher satırın uzunluğunu yazdırır.


0

Diğer bir kolay yol, bunu unix ortamlarının çoğuna önceden yüklenmiş olarak gelen python'da yapmaktır. Aşağıdaki kodu bir .py dosyasına bırakın:

with open('geno') as f:
    for line in f:
        count = 0
        for word in line.split():
            if word != 'N':
                count += 1
        print(count)

Ve sonra yapın:

python file.py

Terminalinizden. Yukarıdakilerin yaptığı:

  • "geno" adlı bir dosyadaki her satır için
  • 0'a bir sayaç ayarlayın ve her değer bulduğumuzda artırın! = 'N'
  • geçerli satırın sonuna ulaşıldığında sayacı yazdırın ve sonraki satıra gidin
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.