0

I've got a text file containing two columns, like so:

26 0.000342231
27 0.000342231
28 0.000684463
29 0.00136893
30 0.00102669
31 0.00308008
32 0.00308008
33 0.00444901
34 0.00718686
35 0.00718686
36 0.0109514
37 0.0123203
...

I'd like to loop over the text file and store each columns value to an associative array - something like a dictionary. If possible I'd like to keep data types of values in each column (int and float).

For a calculation I then need to sum up 2nd column's values for a particular interval till the end of the file, e.g. "sum up 29's (1st column) associated value (0.00136893) down to the last associated value"

What's the best way to do so? Bash and python solutions are most welcome!

1
  • 1
    Please provide an example of your intended output.
    – user167612
    Commented Apr 20 at 14:56

2 Answers 2

2

edit, I misread the question and answered something you weren't asking. Did you want the column entries to be the dictionary keys? So you can check for duplicates when more data arrives? If not, you don't need an associative array, just normal indexed. That will let you start from wherever.

Bash doesn't do FP math at all, so having the data in a bash array isn't useful. >.<

If you want integer indices, and the indices can't be negative, then you should use an indexed array, not an associative (string-indexed) array.

Use a while read loop to parse the input into two variables, then set an array with them.

declare -a arr
# declare -A arr  # associative

while read c1 c2 leftovers;do
    arr[c1]=$c2;
done < file.txt

echo "arr[4] == ${arr[4]}"

You don't actually need declare -a, you can just start using it. Also note that "${#arr}" is the number of set element in the array, not necessarily the last index. (use arr[-1] to access the last element.) "${!arr[@]}" is the list of indices (keys).

All the other things from the bash manual work, too, of course.

1
  • @leo I rolled your comment back since i) in this case, the OP made it clear that the indices are ints, and ii) the $ is completely optional in that context. For example, c=2; arr[c]="foo"; echo "${arr[c]}" works just as well as echo "${arr[$c]}" or ${arr[2]}.
    – terdon
    Commented Apr 20 at 15:11
0

with bash:

arr1=( $( cut -d' ' -f1 file ) )
arr2=( $( cut -d' ' -f2 file ) )

i.e. cut -field 1 (or 2) using space as -delimiter and assign the output to an array.

bash does not distinguish data types in variables, the first index number for any array is 0.

Sum with bash and bc

echo ${arr2[@]} | sed 's/ /+/g' | bc -l

i.e. print all array elements (with space as separators), replace spaces with '+', send to bc -l for doing the actual math operation.

2
  • This is reading the file twice, isn't it?
    – Jason
    Commented Aug 11, 2018 at 15:02
  • It is. Also not too effective but OP preferred bash solutions. I'd strongly suggest awk for such column-based jobs.
    – FelixJN
    Commented Aug 12, 2018 at 19:47

You must log in to answer this question.

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