SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#1 2014-01-21 00:45:37

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Bash Arrays

Hi!

Once again I turn to you guys - you've helped me a lot before.

I've just discovered arrays in bash - but I have problems expanding their values. Here's part of the script:

#!/bin/bash
 
h=(4 100 0 0 0 0 0 0)
i=(2 100 0 0 0 0 0 0)
y=(1 300 1 100 2 300 0 0)
c=(1 300 1 100 1 300 1 100)

tekst_inn="h i c" #Dummy for input

tekst_inn_ARRAY=(`echo $tekst_inn | tr " " "\n"`)

for x in "${tekst_inn_ARRAY[@]}"
  do
    bokstav="\$$x" #Converts all input letters to $LETTER, which are the variable arrays above
 
    echo ${bokstav[@]} #Prints the entire array, which is understandable
    echo ${bokstav[0]}  #Prints the entire array - WHY? Should print "$h" or produce an error..
    echo ${bokstav[1]}  #Prints the entire array - WHY? Should print "$i" or produce an error..

 done

 echo ${bokstav[@]}    #Prints the last element in the array, "$c". Should produce the entire array, shouldn't it?
 echo ${bokstav[0]}     #Prints the last element in the array, "$c". Should produce "$h", shouldn't it?

Here's the output when the code above is ran:

$ ./script.sh 
$h
$h

$i
$i

$c
$c

$c

In addition to the questions in the code comments, here's this; If I'm able to echo a specific element of the array "bokstav" - how to expand that element to the array variables at the top?

Thanks in advance, we'll solve this=)

Cheers, Kols

Last edited by kols (2014-01-21 01:12:11)


I mostly code at night. Mostly.

Offline

Help fund CrunchBang, donate to the project!

#2 2014-01-21 01:49:02

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

For those who might wonder what this script is supposed to do once it's done - it's a script that converts a word to morse code via the speakers;) for example, "y=(1 300 1 100 2 300 0 0)" is "dah dit dah dah" which is, of course, the letter Y. Starting from the first number and going forwards counting every other number is the repetition of beeps, and the rest is the length of the beep. If you look at $c, you'll see that the last two numbers are also used (=/= 0). I've identified that the international morse code has a maximum of four "groups" of sounds for letters. What I mean is, that "-" is one group, "-_" is two groups, "-_-" is three groups, and "-_-_-" is four groups. So when I'm done, the whole alphabet of letters will have this format.


I mostly code at night. Mostly.

Offline

#3 2014-01-21 05:47:05

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

At first glance you aren't loading a "bokstav" array. It just echos the value of "x" each time it loops.
So your final echos just print out the current x value ie $c

I haven't done this for a long time in bash, but I guess that you should declare a bokstav array, then load the next index every time you loop, using a counter. eg

n=n+1
bokstav[n]=$x

(using the correct syntax of course smile )

EDIT

Try

n=0
for x in "${tekst_inn_ARRAY[@]}"
    do
        bokstav[n]=$x
        n=$n+1
    done

echo ${bokstav[@]}   # now prints whole array
echo ${bokstav[0]}    # now prints first element

(Post your final script if you finish it - it sounds interesting smile )

Last edited by damo (2014-01-21 06:31:56)

Offline

#4 2014-01-21 08:30:12

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:

At first glance you aren't loading a "bokstav" array. It just echos the value of "x" each time it loops.
So your final echos just print out the current x value ie $c

Try

n=0
for x in "${tekst_inn_ARRAY[@]}"
    do
        bokstav[n]=$x
        n=$n+1
    done

echo ${bokstav[@]}   # now prints whole array
echo ${bokstav[0]}    # now prints first element

(Post your final script if you finish it - it sounds interesting smile )

Thanks a lot! At least I think I know what's going on there, hehe.. I can't wait to get home from work and try this! Yeah, I'll definitely post the final script!=)

Next task, now that the arrays allows for extraction of each element, is to create another for-loop that will look at what each "bokstav" contains, and send those values to four different commands containing "beep" - one for each group. This may or may not lead to question number two, how to extract the values of each "bokstav".

Anyways, again, thanks for your help. It's so nice to be able to get help with these problems; I seem to be fairly good at building a logic structure of my scripts, I'm just not that good with programming yet;)

BTW, Imagine getting this script to work, then making a script that could recognize the morse code sounds and convert them back to letters! hehe


I mostly code at night. Mostly.

Offline

#5 2014-01-21 09:01:16

ehde
Member
Registered: 2013-10-08
Posts: 18

Re: Bash Arrays

In case you have just one array you could also populate the arguments of the script.

me@myhost:~$ TEST="A B C"
me@myhost:~$ set ${A[@]}
me@myhost:~$ echo $1
A
me@myhost:~$ echo $2
B
me@myhost:~$ echo $3
C
me@myhost:~$ echo $@
A B C
me@myhost:~$ echo $#
3

Offline

#6 2014-01-21 16:31:22

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

Next task, now that the arrays allows for extraction of each element, is to create another for-loop that will look at what each "bokstav" contains, and send those values to four different commands containing "beep" - one for each group. This may or may not lead to question number two, how to extract the values of each "bokstav".

You could loop through the array with while, then use a case statement to choose the required actions

Offline

#7 2014-01-21 17:30:50

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:

Next task, now that the arrays allows for extraction of each element, is to create another for-loop that will look at what each "bokstav" contains, and send those values to four different commands containing "beep" - one for each group. This may or may not lead to question number two, how to extract the values of each "bokstav".

You could loop through the array with while, then use a case statement to choose the required actions

Hey!

I've set up the array to loop through "bokstav", but I'm not sure how to access/expand the letters "bokstav" expand. (for instance        "c=(1 300 1 100 1 300 1 100)"

Cheers!


I mostly code at night. Mostly.

Offline

#8 2014-01-21 17:56:00

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

Use regular expressions/awk/sed?

With awk you could use the spaces as delimiters, then access each field

Offline

#9 2014-01-21 22:13:31

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:

Use regular expressions/awk/sed?

With awk you could use the spaces as delimiters, then access each field

Basically, what I need to do is this (general example)

abc=(a b c)
def=(d e f)
ghi=(g h i)

array=(abc def ghi)

echo ${array[@]}

#which, with some bash magic, should lead to 

a

b

c

d

e

f

g

h

i

#and also this

echo ${array[0]}

a

d

g

Is this even possible?

cheers;)


I mostly code at night. Mostly.

Offline

#10 2014-01-22 00:01:29

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

You aren't getting any help from a bash guru btw, just me big_smile

Am I right in thinking that you want to be able to type a letter, and have the morse signal output through the speaker immediately? You should be able to do that with arrays, but another possibility is to just take the keystroke with read, then pass that to a case statement...

case $1 in
    a )   beep command for "a";;
    b )   beep command for "b";;
    .
    .
esac

Check the keystroke first to only accept allowed characters eg letters and numerals - anything else to exit.
Put it all in an infinite while loop, so it doesn't exit until you Ctrl-C or you use a non-allowed keystroke

Offline

#11 2014-01-23 22:55:33

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:

You aren't getting any help from a bash guru btw, just me big_smile

Am I right in thinking that you want to be able to type a letter, and have the morse signal output through the speaker immediately? You should be able to do that with arrays, but another possibility is to just take the keystroke with read, then pass that to a case statement...

case $1 in
    a )   beep command for "a";;
    b )   beep command for "b";;
    .
    .
esac

Check the keystroke first to only accept allowed characters eg letters and numerals - anything else to exit.
Put it all in an infinite while loop, so it doesn't exit until you Ctrl-C or you use a non-allowed keystroke

Hoi hoi!

I'm leaning towards this solution as well, but I'm gonna try a little more. Also, you know more than me, so;)

I found this code segment on the electronic spider thing. It does sort of what I want, please try it!

#!/bin/bash
abc=(a b c)
def=(d e f)
ghi=(g h i)
array1=(abc def ghi)
cnt=0
total_Array=${#array1[*]}
no_loop_thru=${#abc[*]}

while [ $cnt -lt $total_Array ] ; do
	srch_fld=${array1[$cnt]}
	j=0
	while [ $j -le $no_loop_thru ] ; do
		eval var1=\${$srch_fld[$j]}
		echo ${var1}     # This prints the whole array - no wonder there
		echo ${var1[0]} #Try commenting in and out this here thingy
		((j=j+1))
	  done
		((cnt=cnt+1))
done																			

The commented line there does not do what I expect it do. The code is able to print the values of the three first arrays, but they're not really usable! "echo ${var{0]}" does not give me the first element of each array.. I find that strange. If we get this to work, my script is done. The rest is all sorted out;)


I mostly code at night. Mostly.

Offline

#12 2014-01-23 23:49:30

aiBo
#! CrunchBanger
Registered: 2010-11-08
Posts: 243

Re: Bash Arrays

Does this give you the desired behaviour? For me it prints in this case the second element of each array.


abc=(1 2 3)
def=(d e f)
ghi=(g h i)

array1=(abc def ghi)

for s in ${array1[@]}
do 
  eval 'echo "${'"$s[1]"'}"'
done

This solution is based on tips from the bash hackers wiki:
http://wiki.bash-hackers.org/syntax/pe

However, since Bash doesn't support multidimensional arrays, this approach won't get any less ugly.

Offline

#13 2014-01-23 23:57:19

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

@kols

Couple of things I'm noticing:

1) I think you are comparing integers with string variables
2) Find out a bit more about how to quote variables

comparison operators

(Excellent bash resource there btw)

Last edited by damo (2014-01-23 23:58:08)

Offline

#14 2014-01-24 08:50:57

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

aiBo wrote:

abc=(1 2 3)
def=(d e f)
ghi=(g h i)

array1=(abc def ghi)

for s in ${array1[@]}
do
  eval 'echo "${'"$s[1]"'}"'
done

Tweaking this code, and combining it with the while-code above, I was able to write this piece of code, which seems to work (I'm at work =P so I'll have to wait until later to actually try it with the rest)

#!/bin/bash

abc=(1 2 3)
def=(d e f)
ghi=(g h i)

array1=(abc def ghi)
array1_count=${#array1[@]}
#echo ${array1_count[@]}

m=0

while [ $m -le $array1_count ] ; do
	

		for s in ${array1[m]}
			do 
  			eval 'echo "${'"$s[0]"'}"'
  			eval 'echo "${'"$s[1]"'}"'
  			eval 'echo "${'"$s[2]"'}"'
  
		done
		((m=m+1))
done

Thanks goes to all of you!=)


I mostly code at night. Mostly.

Offline

#15 2014-01-24 17:18:47

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:

Thanks

ehde wrote:

Thanks

aibo wrote:

Thanks

(Sorry about the quotes not being quotes from you, but as far as I know, this is the only way to notify you)

Here's the finished script! Works like a charm, one word at a time;)

#!/bin/bash

#script: Morse
#Written by Ole-Jørgen Næss Kolsrud

#Thanks to crunchbangers damo, ehde and aibo!
#Also, thank you, Internet=P

#Dependencies: bash, beep


echo "  " 
echo -e '\E[1;32m'"\033[1mMORSE CONVERTER\033[0m"
echo "  "
echo "Usage: One word at a time, letters must be separated by a space"
echo "  "

while true
	do
		a=(1 100 1 300 0 0 0 0)
		b=(1 300 3 100 0 0 0 0)
		c=(1 300 1 100 1 300 1 100)
		d=(1 300 2 100 0 0 0 0)
		e=(1 100 0 0 0 0 0 0)
		f=(2 100 1 300 1 100 0 0)
		g=(2 300 1 100 0 0 0 0)
		h=(4 100 0 0 0 0 0 0) 
		i=(2 100 0 0 0 0 0 0)
		j=(1 100 3 300 0 0 0 0)
		k=(1 100 1 300 1 100 0 0)
		l=(1 100 1 300 2 100 0 0)
		m=(2 300 0 0 0 0 0 0)
		n=(1 300 1 100 0 0 0 0)
		o=(3 300 0 0 0 0 0 0)
		p=(1 100 2 300 1 100 0 0)
		q=(2 300 1 100 1 300 0 0)
		r=(1 100 1 300 1 100 0 0)
		s=(3 100 0 0 0 0 0 0)
		t=(1 300 0 0 0 0 0 0)
		u=(2 100 1 300 0 0 0 0)
		v=(3 100 1 300 0 0 0 0)
		w=(1 100 2 300 0 0 0 0)
		x=(1 300 2 100 1 300 0 0)
	    y=(1 300 1 100 2 300 0 0)
		z=(2 300 2 100 0 0 0 0)
		
		read -p "Text to convert: " tekst_inn

		tekst_inn_ARRAY=(`echo $tekst_inn | tr " " "\n"`)

		an=0

		for ax in "${tekst_inn_ARRAY[@]}"
    	do
				bokstav[an]=$ax
				an=$an+1
		done
		
		bokstav_count=${#bokstav[@]}
		
		am=0

		while [ $am -le $bokstav_count ] ; do
				
				for as in ${bokstav[am]}
					do 
  					eval 'morse0="${'"$as[0]"'}"'
  					eval 'morse1="${'"$as[1]"'}"'
  					eval 'morse2="${'"$as[2]"'}"'
						eval 'morse3="${'"$as[3]"'}"'
						eval 'morse4="${'"$as[4]"'}"'
						eval 'morse5="${'"$as[5]"'}"'
						eval 'morse6="${'"$as[6]"'}"'
						eval 'morse7="${'"$as[7]"'}"'
												
						beep -r $morse0 -d 300 -f 1000 -l $morse1 #Kjører første gruppe
						sleep 0.3
						beep -r $morse2 -d 300 -f 1000 -l $morse3 #Kjører andre gruppe
						sleep 0.3
						beep -r $morse4 -d 300 -f 1000 -l $morse5 #Kjører tredje gruppe
						sleep 0.3
						beep -r $morse6 -d 300 -f 1000 -l $morse7 #Kjører fjerde gruppe
				done
				((am=am+1))
		done
unset bokstav[@]
done

Edit: Found some bugs

Last edited by kols (2014-01-24 17:40:21)


I mostly code at night. Mostly.

Offline

#16 2014-01-24 18:19:06

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

kols wrote:

Thanks damo. Please pm me so I can credit your PayPal account

devil kiss

Offline

#17 2014-01-24 18:31:19

kols
#! CrunchBanger
From: Norway
Registered: 2013-03-22
Posts: 151

Re: Bash Arrays

damo wrote:
kols wrote:

Thanks damo. Please pm me so I can credit your PayPal account

devil kiss

I said that? damn.. Well, I guess I'd have to pay you, then?=P
Jokes aside, I'm very thankful for the help. I've learned a lot! And the script is pretty fun to use as well;) Now I can have people write stuff, and I'll try to decode what they wrote. I wanna learn morse, that's why I wrote the script, hehe


I mostly code at night. Mostly.

Offline

#18 2014-01-24 19:44:42

damo
#! gimpbanger
From: N51.5 W002.8 (mostly)
Registered: 2011-11-24
Posts: 5,200

Re: Bash Arrays

NP

Don't forget you can contact people via email or personal message if they have that enabled

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.

Debian Logo