Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

count numbers column by column 1

Status
Not open for further replies.

userand

Technical User
Apr 12, 2011
28
CH
Hi,

could anyone help me how should I count the number of "ones" in the following record in that way that counts every 16 blocks

0000001000010000000100100000100100000000000000000000001000000000

so it should be counted the "ones" in

0000001000010000 and 0001001000001001 and 0000000000000000 and 0000001000000000

?
 
Try
Code:
{
  for (j=1;j<=length;j+=16) {
    a=substr($0,j,16)
    print gsub(/1/,"",a)
  }
}

CaKiwi
 
Hi

Just as a curiosity, a loopless [tt]gawk[/tt]-only solution :
Code:
awk --re-interval -vRS='.{16}' '{print length(gensub(/[^1]/,"","g",RT))}' /input/file
CaKiwi, thanks for refreshing my memory. [medal] I always forget that [tt]gsub()[/tt] has a return value.

Feherke.
 
Hi,

thanks for the solutions, both of them.

A last question: I would like to check if all of the number of ones are the same in each block or not.
I have tried to write this, but not working properly:

{
for (j=1;j<=length;j+=16) {
a = substr($0,j,16)
b = gsub(/1/,"",a)

if( (i==1 && b==2) && (i==17 && b==4) && ... )
print substr($0,i,16) // or print $0
else
next
}
}

If all of the blocks the number of ones are equal (in case of containing one null block at least), print the whole row, else get the next record...
This is a naive way so far, so please help me a little...
 
I'm not sure exactly what you want. This program checks each line to see if each block of 16 has the same number of 1's and at least 1 block has no 1's. If both conditions are true, it prints out the line.
Code:
{
  l=length/16
  for (j=0;j<l;j++) {
    a=substr($0,j*16+1,16)
    b[j]=gsub(/1/,"",a)
  }
  x=-1
  nl=0
  for (j=0;j<l;j++) {
    if (b[j]==0)
      nl=1
    else if (x==-1)
      x=b[j]
    else if (x!=b[j])
      next
  }
  if (!nl) next
  print
}
Feherke, your solution had me scrambling for the manual! Very creative!

CaKiwi
 
This does not work... I would like to check if there are exactly the same numbers of "ones" in the block or not.

The code you have presented above gives me the solution: 2, 4, 0, 1. So there are 2, 4, 0, 1 number of ones in the blocks 1-16, 17-32, 33-48, 49-64.

In this case I would like to verify that every blocks has let say 2 "1"-s at most or not. If it has, print the whole line, else get the next record.
 
OK, I get your point, BUT I would like classify the number of occurencies of ones...

Let's say I would like to find (print) this if there exsists:

0010001000000000000100100100000000000000000000000000000000001000

So if there are 2 ones in block 1 and 3 ones in block 2 and 1 one in block 3. If I allow all possible pair in the 1,2,3 sequence...

block-1 block-2 block-3
========================
1 1 1
1 1 2
1 2 1
2 1 1
1 2 2
2 1 2
2 2 1
....
3 3 3
 
Sorry, there are not 3 bloks but 4, as 64/16 = 4 and

you have to take into account the '0'-s in the classifing ...

1 0 1 1
...
3 0 3 2
...
3 3 3 0
...
 
Sorry, I don't understand what you want. Maybe if you post more input data and the exact output that you expect it will be clearer to me

CaKiwi
 
Ok. I would like to filter those lines which are contain for example number of 3 '1'-s at most block by block, and does not contain zero number of '1'-s at all...

For example:

Lines that are fulfill this requirement:

0010000000000000000000000000000000000000000000000000000000000000
0000000000000000000100100100000000000000000000000000000000000000
0010001000000000000100100100000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000111
1100000000000000000000000100000000000001110000000000000000000000

Lines that are NOT fulfill this requirement:

1100000000000000000000000100000000000001111000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
1010100000000000000000000100000000000000110000000000000000110011
1100100001100000000000000100000000000001010000000000000000000000
1000000000000000000000001100000000000001110000000000000000011110
 
This might be what you want
Code:
{
  l=int(length/16)
  nl=0
  for (j=0;j<l;j++) {
    a=substr($0,j*16+1,16)
    x=gsub(/1/,"",a)
    if (x>3) next
    if (x==0) nl++
  }
  if (nl==l) next
  print
}


CaKiwi
 
Thanks a lot! This is not so hard, but I am an idiot...
 
Sorry, a very last question:

how would I count and set gsub(/1/,"",a) a by a ?

I mean:

if(a==1 && x>1)
if(a==2 && x>3)
...

Is it correct?
 
I don't understand what you want. The variable a is set to each set of 16 digits so saying if(a==1... doesn't make any sense. Explain more fully what you want and give examples of the input and output.

CaKiwi
 
I think userand meant this:
if([!]j[/!]==1 && x>1)
if([!]j[/!]==2 && x>3)
...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top