1

In the following I've put up my code for iterating over lines of a file in order to collect data within a segment from the file in following fashion:

Illustration for understanding procedure:

segL                     segH
|                         |
[  2 4 9 15 25 45 ... 99  ] 102 136 ... 206

Later, for a file with 10000 lines I'd like to divide the file into segments of equal length with a lower boundary of segL and segH=segL+segsize.
Walking through the file, I'd like to count the number of integers meeting following condition:
segL < integer =< segH. This number then should be stored in a variable uniquely containing the amount of integers for that very segment only!

Code

segsize=100
segL=0
segH=100
blockcounter=0
segment1=0
segments2=0
#Go through input and partition it
for i in {1..2}
do
    while read p; do
        if [ $p -gt $segL ] && [ $p -le $segH ]
        then
            blockcounter=$(($blockcounter + 1))
        fi
    done <$inputfile

    if [ "$i" -eq "1" ]
    then
        segment1=$blockcounter
        echo "segment1: $segment1"
    fi
    if [ "$i" -eq "2" ]
    then
        segment2=$blockcounter
        echo "segment2: $segment2"
    fi
blockcounter=0
segL=$segH
segH=$(($segL + $segsize))
done

Right now, in my code I'm able to collect data for 2 segments only - with my file, currently, containing a bit more than 200 integers (2*segments).

Output:

segment1: 27
segment2: 33

For larger samples I need to store data into up to 100-120 segments with a comparable output mentioned above.

Can you think of alternatives for achieving same output (2D-array like object for storing data points, e.g. A(segment1|<count of integers>)?

1
  • I didn't quite understand your question (apologies, that's probably me — I'm tired right now), but you can emulate a 2d array in bash with associative arrays: declare -A array then array[seg${i}_int$j]=$value or something along those lines.
    – Muzer
    Jul 23, 2015 at 22:19

1 Answer 1

1

I'm not sure I understand your problem correctly...

#!/bin/bash

segsize=100
segL=0
max=0
a=()

while read p; do
        (( n = (p - segL - 1) / segsize ))
        if (( n + 1 > max )); then
                for ((i = max; i < n + 1; i++)) do
                        a+=(0)
                done
                (( max = n + 1 ))
        fi
        (( a[n]++ ))
done

for ((i = 0; i < max; i++)); do
        echo "segment $((i+1)) ($((segsize*i)), $((segsize*(i+1)))] : ${a[$i]}"
done

Input (each number must be > 0):

1
100
101
200
1000
1001 

Output:

segment 1 (0, 100] : 2
segment 2 (100, 200] : 2
segment 3 (200, 300] : 0
segment 4 (300, 400] : 0
segment 5 (400, 500] : 0
segment 6 (500, 600] : 0
segment 7 (600, 700] : 0
segment 8 (700, 800] : 0
segment 9 (800, 900] : 0
segment 10 (900, 1000] : 1
segment 11 (1000, 1100] : 1
1
  • Apparently, my description of my question was successfull. Thanks a lot, that't exactly what I was looking for! Jul 24, 2015 at 5:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .