You are not logged in.
I'm new to bash (my only programming background is a single class in C), but am working on a script right now and have run into some issues with it.
1) I have a text file containing a long list of (space separated) numbers, which I would like the script to read and place into a one dimensional array. So I could run the script with something like:
$ ./script_name text_file.txt
There will be 200 elements in the array. What's the best way to do this (read the text file into the array)?
2) I'm trying to create a new array (array2), in which each element is calculated from the elements in different array. As a simple test case of this I wrote:
array1=( 0 1 2 3 4 5 6 7 8 9 )
array2=( 0 0 0 0 0 0 0 0 0 0 )
arrayA=( 0 1 2 3 4 5 6 7 8 9 )
const1=10
constA=5
for((i=0;i<10;i++))
do
array2[$i]+="bc 'scale=20;${array1[$i]}-${arrayA[$i]}*$const1/$constA'" # fix this
done
However the line evaluating array2 doesn't work right. I think I need single quotes instead of double quotes around the bc command. The problem then is when the second set of quotes open up, it reads it as closing the first set. What's the correct way to do this?
Offline
for ((i=0;i<10;i++))
do
array2[$i]+=$(bc "scale=20;${array1[$i]}-${arrayA[$i]}*$const1/$constA")
done
The double quotes treat it as a string, not an external executable to run and return the result. Note the change of the inside quotes to double quotes. Single quotes won't allow the variables to be interpolated into their corresponding values and will pass literal '${array...}' strings to bc instead.
Are you familiar with our Forum Rules, and How To Ask Questions The Smart Way?
BlueHackers // fscanary // resticctl
Offline
From what I remember, bc only reads from standard input, not command line arguments. For example, like this:
echo 2+2 | bc
Offline
I'm not sure why you are using bc, bash has arithmitic capabilities built in. Is the following the equivalent of what your test script was trying to do?
#!/bin/bash
array1=( 0 1 2 3 4 5 6 7 8 9 )
arrayA=( 0 1 2 3 4 5 6 7 8 9 )
const1=10
constA=5
for((i=0;i<10;i++))
do
(( array2[$i]=${array1[$i]}-${arrayA[$i]}*$const1/$constA ))
echo ${array2[$i]}
done
Note the use of double parenthises (( ... )). This is one way where bash "does" arithmetic. (There are other ways.)
Reading data from a file can be a little tricky. The following assumes that your data is in a file named 'foo'.
If each data point is on a separate line, the following will read each data value in turn into the variable 'dp':
#!/bin/bash
i=0
while read dp
do
(( array[$i]=$dp*2 ))
(( i++ ))
done < foo
If each data point is separated by whitespace (spaces, tabs or newlines), the following will work:
#!/bin/bash
i=0
data=$(cat foo)
for dp in $data
do
(( array[$i]=$dp*2 ))
(( i++ ))
done
Edit: I see I didn't actually answer your question. To read a data file into an array (each data point is separated by whitespace) do:
declare -a x=$(cat foo)
should do it.
Last edited by rockin turtle (2011-04-05 05:35:41)
Offline
For reading lines of a file into an array you can use mapfile
mapfile array < filename
and space-seperated values can be read into an array using
array=( $(< filename) )
Edit: i just realized that the second will work for both, space and newline seperated data.
Last edited by portix (2011-04-05 09:23:43)
Offline
For reading lines of a file into an array you can use mapfile
mapfile array < filename
and space-seperated values can be read into an array using
array=( $(< filename) )
Edit: i just realized that the second will work for both, space and newline seperated data.
It will, to an extent. you would have to sent IFS=$'\n', and set -f, in order to keep glob characters from expanding to filenames.
The preferred way is with mapfile, or a while read loop
while read -r line; do
array+=("$line")
done < filename
for space separated, you can use the nice read one liner:
read -rd '' -a array < filename
Last edited by freak (2011-04-19 15:10:59)
Offline