Bagaimana cara menghitung jumlah karakter dalam satu baris, kecuali karakter tertentu?

9

Ini adalah file bagian

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

Di setiap baris saya ingin menghitung jumlah total semua karakter yang bukan "N"

output keinginan saya

1
1
1
0
1
2
2
Anna1364
sumber
Gunakan seduntuk mengganti barang-barang yang tidak Anda pedulikan dan awkuntuk menghitung panjang yang tersisased 's/N//g ; s/\s//g' file | awk '{ print length($0); }'
Rolf

Jawaban:

13

Solusi awk GNU :

awk -v FPAT='[^N[:space:]]' '{ print NF }' file
  • FPAT='[^N[:space:]]'- pola yang mendefinisikan nilai bidang (karakter apa pun kecuali Nkarakter dan spasi)

Output yang diharapkan:

1
1
1
0
1
2
2
RomanPerekhrest
sumber
9
awk '{ gsub("[ N]",""); print length() }'
Hauke ​​Laging
sumber
juga dapat menggunakanawk '{print gsub(/[^ N]/,"")}'
Sundeep
7

dengan asumsi bahwa hitungan diperlukan untuk setiap baris selain karakter spasi dan N

$ perl -lne 'print tr/N //c' ip.txt 
1
1
1
0
1
2
2
  • nilai balik tradalah berapa banyak karakter yang diganti
  • c untuk melengkapi set karakter yang diberikan
  • Perhatikan penggunaan -lopsi, menghapus karakter baris baru dari jalur input untuk menghindari kesalahan satu per satu dan juga menambahkan karakter baris baru untuk pernyataan cetak


Solusi yang lebih umum

perl -lane 'print scalar grep {$_ ne "N"} @F' ip.txt 
  • -apilihan untuk secara otomatis membagi jalur input pada spasi putih, disimpan dalam @Farray
  • grep {$_ ne "N"} @Fmengembalikan array semua elemen @Fyang tidak cocok dengan stringN
    • setara regex akan menjadi grep {!/^N$/} @F
  • Penggunaan scalarakan memberikan sejumlah elemen array
Sundeep
sumber
6

Solusi awk alternatif :

awk '{ print gsub(/[^N[:space:]]/,"") }' file
  • gsub(...)- gsub()Fungsi mengembalikan jumlah penggantian yang dibuat.

Hasil:

1
1
1
0
1
2
2
RomanPerekhrest
sumber
6

awkPendekatan lain (akan mengembalikan -1 untuk baris kosong).

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

Atau dalam kompleks, itu akan mengembalikan -1 pada baris kosong, 0 pada baris spasi putih (Tab / Spasi) saja.

awk -F'[^N \t]+' '$0=NF-1""' infile
αғsнιη
sumber
akan mencetak -1untuk garis kosong ... tapi kemudian itu mungkin diinginkan untuk membedakan garis yang hanya terdiri dari N / spasi vs garis kosong ...
Sundeep
1
@ Tetap Ya, itu benar. juga melihat pembaruan saya di mana baris hanya berisi Tab atau Spasi untuk menunjukkan sebagai 0
αғsнιη
5
  1. trdan skrip shell POSIX :

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

    while read x ; do x="${x//[ N]}" ; echo ${#x} ; done < file
    
agc
sumber
1
dapat digunakan awk '{print length()}'untuk menghindari perulangan shell yang lebih lambat .. tapi kemudian orang bisa melakukan semuanya dengan awk sendiri ...
Sundeep
@ Simpan, Itu benar, ( jika keduanya dimulai pada saat yang sama), awkperulangan itu lebih cepat daripada perulangan shell. Tapi shell selalu ada di memori, dan awkmungkin tidak - ketika awkbelum dimuat, atau ditukar, overhead memuatnya, ( waktu yang hilang ), bisa lebih besar daripada keuntungan berjalan awk- terutama pada kecil lingkaran. Dalam kasus seperti itu, ( yaitu kasus ini), awkbisa lebih lambat .
agc
baik, tentu saja saya tidak khawatir tentang waktu untuk hal-hal kecil ... lihat unix.stackexchange.com/questions/169716/…
Sundeep
1
@Sundeep, saya lakukan khawatir. Beberapa waktu yang lalu saya menggunakan distro Linux berbasis floppy , yang dapat menjalankan floppy, dalam beberapa MB ram. Tidak perlu menggunakan awkdalam skrip shell bisa membuat sistem merangkak merangkak seperti itu. Secara umum: hambatan latensi yang sama berlaku untuk sistem dalam firmware terbatas, atau sistem apa pun di bawah beban berat.
agc
1

Kombinasi singkat trdan awk:

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

Ini menghapus semua spasi Ns dari file input dan awkhanya mencetak panjang setiap baris.

Kusalananda
sumber
0

Cara mudah lainnya adalah melakukannya dengan python, yang sudah diinstal sebelumnya di sebagian besar lingkungan unix. Letakkan kode berikut dalam file .py:

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

Dan kemudian lakukan:

python file.py

Dari terminal Anda. Apa yang dilakukan di atas adalah:

  • untuk setiap baris dalam file bernama "geno"
  • atur penghitung ke 0 dan tambahkan setiap kali kita menemukan nilai! = 'N'
  • ketika akhir dari garis saat ini tercapai, cetak penghitung dan pergi ke baris berikutnya
Grajdeanu Alex.
sumber