Colum number where value is >0

Hi All
I want to findout coloum number where value is >0 from below string
Can we do using awk or any command ?
Thanks in advance

2016-08-04-0000,619,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,0,0,0,0,5,8,0,0,0,0,0,0,0,0,0,3,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,1,0,0,0,39,0,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,
0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

Hello aaysa123 ,

I have a few to questions pose in response first:-

  • Is this homework/assignment? There are specific forums for these.
  • What have you tried so far?
  • What output/errors do you get?
  • What OS and version are you using?
  • What are your preferred tools? (C, shell, perl, awk, etc.)
  • What logical process have you considered? (to help steer us to follow what you are trying to achieve)

Most importantly, What have you tried so far?

There are probably many ways to achieve most tasks, so giving us an idea of your style and thoughts will help us guide you to an answer most suitable to you so you can adjust it to suit your needs in future.

We're all here to learn and getting the relevant information will help us all.

Kind regards,
Robin

1 Like

I have tried but it is not giving required o/p

awk -F',' ' { for (i = 1; i <= NF; ++i) print i, $i; exit } ' test

What about adding a comparisson if $i is greater than 0? If so, maybe print $i and NR so you know which line it is found at.
If you can write an awk statement like this, you can surely add this. Try it.

1 Like

Longhand, using Macbook Pro, circa August 2012, OSX 10.7.5, default bash terminal.
Assumption made that the OP added the newlines in the string to shorten said string.

#!/bin/bash
# Extract numbers longhand.
# OSX 10.7.5, default bash terminal.
ifs_org="$IFS"
IFS=",
"
echo '2016-08-04-0000,619,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,0,0,0,0,5,8,0,0,0,0,0,0,0,0,0,3,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,1,0,0,0,39,0,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,
0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' > /tmp/text
NUM_ARRAY=( $( cat /tmp/text ) )
ARRAY_LEN=${#NUM_ARRAY[@]}
# Deliberately miss out the date stamp.
n=1
while [ $n -le $((ARRAY_LEN-1)) ]
do
	if [ "${NUM_ARRAY[$n]}" -gt "0" ]
	then
		echo "${NUM_ARRAY[$n]}"
	fi
	n=$((n+1))
done
IFS="$ifs_org"
exit 0

Results...

Last login: Thu Aug  4 13:33:49 on ttys000
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> ./numextract.sh
619 
619 
89 
5 
8 
3 
2 
3 
211 
1 
39 
105 
14 
5 
AMIGA:barrywalker~/Desktop/Code/Shell> _

You now know that a comparison test is required somewhere, so apply this technique to your awk code.

This will work with several shells and won't with others. Some shells (honestly, i don't know if bash is among them) have limits on the maximum numbers of elements an array can hold: ksh88 for instance 1023, ksh93 more than that, even if i can't remember how many.

It is usually best to stay as far away as possible from the limits, so i wouldn't use arrays for any data which could even come into the vicinity of 1000, but arguably my scripting style is far too defensive to be optimal. Having had to administrate abour 20k servers worldwide once did that for me: every conceivable nightmare was sure to be encountered on at least half a dozen systems and one gets to take absolutely nothing for granted.

How about this, using shell methods:

(( iCnt = 1 ))
string="0,0,0,0,0,3,0,0,1,0," # [....]
buf=""
rest="$string"

while [ -n "$rest" ] ; do
     rest="${string#[0-9]*,}"
     buf="${string%,$rest}"

     if (( $buf )) ; then
          echo "Element $iCnt is $buf"
     fi

     (( iCnt = iCnt + 1 ))
     string="$rest"
done

I hope this helps.

bakunin

1 Like

Well I know my version of bash can do 192000 elements as I have used it in the past:-
(Whistling into the built-in microphone...)

#!/bin/bash
# arraylimit.sh
SECS=1
"$HOME"/sox-14.4.2/sox -q -V0 -d -t raw -r 96000 -b 8 -c 2 -e unsigned-integer -> /tmp/rawfile trim 0 00:"$SECS"
arraylimit=( $( hexdump -v -e '1/1 "%u "' /tmp/rawfile ) )
echo "${#arraylimit[@]}"
echo "${arraylimit[191999]}"

Results...

Last login: Thu Aug  4 16:53:26 on ttys000
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
AMIGA:barrywalker~/Desktop/Code/Shell> ./arraylimit.sh
192000
121
AMIGA:barrywalker~/Desktop/Code/Shell> _

IIRC I have had an array with double that, (384000 elements), for another reason.

With the missing if condition:

awk -F',' '{ for (i = 1; i <= NF; ++i) { if ($i > 0) { print i, $i } } }' test

Sometimes one can save the for loop by means of the RS (record separator)

awk 'BEGIN { RS="," } ($1 > 0) { print NR, $1 }' test
1 Like