I am new to shell scripting. I am trying to create an array of size n, where n is input by the user during the run time.
while [ $i -lt $n ]
do
echo For person $i enter the name?
read io
eval Name[$index]= $io
done
When I try to do this, the values are overwritten every time the loop gets the input from user.
For ex: if person 1 is - Tom,if person 2 is - John. Then when i try to print the names of all person at the end of the script, person 1 name is overwritten with person n th name.(which means, all names are stored in a single variable instead of an array).
Can someone tell me where am i going wrong?
You need to increment i in the loop so that it eventually exits. This line increments i by 1:
let i+=1
You don't need to use eval in eval Name[$index]= $io.
There is no variable named index (at least not in your code sample). I assume you meant to use i there. (i.e., Name[$index] should be Name[$i])
This code works:
#!/bin/sh -e
Name=()
i=0
while [ $i -lt 4 ]
do
echo For person $i enter the name?
read io
Name[$i]=${io}
let i+=1
done
echo names:
for n in "${Name[#]}"
do
echo $n
done
Related
I have wasted so much of my time with this, I hope someone can help me. I am editing a script that is used to send values to an executable and then scrubs the output from the executable for tabulation. I have created two arrays that are filled with user inputted ranges, these ranges are then used to create a nested loop that I have put into a function (since I need to create 4 files from the output depending on another value). I admit that my code is abysmal, but it does the primary thing and that is obtaining the data I need and puts into the correct file. All I am trying to do is to get it to actually make a table with row and column labels, I just can't understand why this is so difficult.
This is the problematic area:
# Function to loop user inputted ranges in order to generate report data.
function repeat()
{
printf "%22s" 'density (10^18 m^-3)'
for a in "${density_array[#]}" # for loop to list density values in the range set by the user.
do
printf "%13s" "$a"
done
echo -e "\n" 'speed (m/s)'
#printf "%s\n" "${speed_array[#]}"
for i in "${speed_array[#]}"
do
echo "$i"
for j in "${density_array[#]}"
do
echo $j > SCATINPUT # generates a temporary file named SCATINPUT, with density value as first line.
echo $temp >> SCATINPUT # appends a new line with temperature value to SCATINPUT file.
echo $i >> SCATINPUT # appends a new line with speed value to SCATINPUT file.
echo $1 >> SCATINPUT # appends a new line with rate type from argument to SCATINPUT file.
# pipes contents of SCATINPUT file to executable, extracts value from STDOUT to RATE variable.
RATE=`path_of_executable < SCATINPUT | awk '/0\./'`
RATEF=$(printf "%.4e" $RATE) # converts number in RATE variable to scientific notation with 4 digits after decimal and sets RATEF variable.
echo -ne "\t$RATEF"
rm -f SCATINPUT # quietly deletes SCATINPUT file.
done
done
}
I am getting this output in a file:
density (10^18 m^-3) 2.0000e+00 4.0000e+00 6.0000e+00
speed (m/s)
8.0000e+06
7.6164e+04 1.4849e+05 2.1936e+059.0000e+06
5.7701e+04 1.1249e+05 1.6619e+051.0000e+07
4.3469e+04 8.4747e+04 1.2520e+051.1000e+07
3.3078e+04 6.4488e+04 9.5269e+041.2000e+07
2.5588e+04 4.9886e+04 7.3697e+04
But it should be this:
density (10^18 m^-3) 2.0000e+00 4.0000e+00 6.0000e+00
speed (m/s)
8.0000e+06 7.6164e+04 1.4849e+05 2.1936e+05
9.0000e+06 5.7701e+04 1.1249e+05 1.6619e+05
1.0000e+07 4.3469e+04 8.4747e+04 1.2520e+05
1.1000e+07 3.3078e+04 6.4488e+04 9.5269e+04
1.2000e+07 2.5588e+04 4.9886e+04 7.3697e+04
The general idea would be to replace the echo commands with comparable printf commands with formats that match the formats used to print the first/header line ...
Start by replacing echo "$i" with printf "%22s" "$i" => this should leave the cursor on the same line as $i and lined up under the 2.0000e+00
After you finish the j loop and before getting the next i do printf "\n" => this should move the cursor to the next line and ready for the next printf "%22s" "$i".
That should get you started.
If things don't line up quite right then consider replacing the echo -ne "\tRATEF" with a printf "%#s" "$RATEF" (adjust the number # to line up output as desired).
I have wrote a script that throws the output of running node processes with the cwd of that process and I store the value in an array using for loop and do echo that array.
How can I able to get the user enter the index of array regarding the output that the script throws and show the output against that input generated by user
Example Myscript
array=$(netstat -nlp | grep node)
for i in ${array[*]}
do
echo $i
done
output is something like that
1056
2064
3024
I want something more advance. I want to take input from user like
Enter the regarding index from above list = 1
And lets suppose user enter 1
Then next output should be
Your selected value is 2064
Is it possible in bash
First, you're not actually using an array, you are storing a plain string in the variable "array". The string contains words separated by whitespace, so when you supply the variable in the for statement, the unquoted value is subject to Word Splitting
You need to use the array syntax for setting the array:
array=( $(netstat -nlp | grep node) )
However, the unquoted command substitution still exposes you to Filename Expansion. The best way to store the lines of a command into an array is to use the mapfile command with a process substitution:
mapfile -t array < <(netstat -nlp | grep node)
And in the for loop, make sure you quote all the variables and use index #
for i in "${array[#]}"; do
echo "$i"
done
Notes:
arrays created with mapfile will start at index 0, so be careful of off-by-one errors
I don't know how variables are implemented in bash, but there is this oddity:
if you refer to the array without an index, you'll get the first element:
array=( "hello" "world" )
echo "$array" # ==> hello
If you refer to a plain variable with array syntax and index zero, you'll get the value:
var=1234
echo "${var[0]}" # ==> 1234
i have a a files containing usernames and users sent count mail per line . for example (dont know how many line have ) :
info.txt >
500 example1
40 example2
20 example3
....
..
.
if the number was greater than X , i want to run commands containing the user name and act on user .
getArray() {
users=() # Create array
while IFS= read -r line # Read a line
do
users+=("$line") # Append line to the array
done < "$1"
}
getArray "/root/.myscripts/spam1/info.txt"
# i know this part is incorrect and need help here :
if [ "${users[1$]}" -gt "50" ]
then
echo "${users[2$] has sent ${users[1$]} emails"
fi
please Help
Thanks
Not knowing how many lines of input you have is no reason to use an array. Indeed, it is generally more useful if you assume your input is infinite (an input stream), so reading into an array is impossible. Just read each line and take action if necessary:
#!/bin/sh
while read -r count user; do
if test "$count" -gt 50; then
echo "$user has sent $count emails"
fi
done < /root/.myscripts/spam1/info.txt
ahhh array and loops my weakest links. I was trying to create array depending on user input so
printf "%s\n" "how may array you want"
read value
after this i will ask what value user want to put on a array(this is the bit im stuck on)
i=1
while [ $i -le $value ]
do
echo "what value you want to put in array $i"
read number
echo $number >> array.db
i=$(( i+1 ))
echo
done
although this method works(i think) but i'm not too sure if i'm actually creating an array and putting value to that array.
you can expand arrays in bash dynamically. you can use this snippet
a=(); a[${#a[#]}]=${number}; echo ${a[#]}
The first statement defines an empty array. with the second (which you can use in your while loop) you insert a value at last elment position + 1, due to ${#a[#]} represents the length of a. the third statement just prints all elements in the array.
i have a shell script for putting values into an array. The script is working fine for me. The problem is, if i put the array inside a for loop (between do and done), and when i try to print the array length outised the loop,i.e, after done, the values are not getting updated. Here is the sameple code;
function _read_value
{
count=0
array[0]="hi"
for ///some condition
do
count++
array[count]="hello"
done
echo ${#array[#]
}
When i try to print the length of the array at the end, it is showing the length as 1.
Any help would be appreciated.
I made some small changes in your script and its updating values and the count also comes fine.(I made change in count increment and in loop)
#!/bin/bash
function read_value
{
count=0
while [ $count -le 5 ]
do
array[count]="hello"
count=`expr $count + 1`
done
echo ${array[#]}
echo ${#array[#]}
}
read_value