I am looing for information on google about declaring array in expect but unable to find it.even the witki link for the line is empty.
I know i can set array values like set arr("hh") "hhh" but how do i declare it.
and can i print the whole array using one command or do i have to loop through it to print all the elements.
Or there is no such thing as declaring array in expect/tcl.i mean can we access any array
just by using global keyword.
You don't have to declare an array, but if you want to:
array set variableName {}
The last word is an empty list. If you have some default values you want to store in the array, you can say:
array set varname {key1 val1 key2 val2 ... ...}
If you're curious, here's how parray is implemented:
proc parray {a {pattern *}} {
upvar 1 $a array
if {![array exists array]} {
error "\"$a\" isn't an array"
}
set maxl 0
set names [lsort [array names array $pattern]]
foreach name $names {
if {[string length $name] > $maxl} {
set maxl [string length $name]
}
}
set maxl [expr {$maxl + [string length $a] + 2}]
foreach name $names {
set nameString [format %s(%s) $a $name]
puts stdout [format "%-*s = %s" $maxl $nameString $array($name)]
}
}
You don't declare arrays in Expect (or Tcl in general) you just use them.
But arrays and other variables do have scope. If you are in a proc and want to
refer to an array arr which has global scope you can either say global arr before
using it or prefix the name with :: each time you use it, eg. set ::arr(hh) "hhh"; puts $::arr(hh).
There is a command parray to print a whole array, but this is loaded from library scripts rather than being built-in, so may not be available depending on how your Expect installation has been done. Eg.
expect1.1> set arr(a) ACBD
ACBD
expect1.2> set arr(b) "BBB bbb"
BBB bbb
expect1.3> parray arr
arr(a) = ACBD
arr(b) = BBB bbb
Related
Given the enumeration
enum NATO (:alpha<A>, :bravo<B>, :charlie<C>, :delta<D>);
it's possible to easily set a variable by literally typing one of the names, or by passing one of the values to the enum object:
my $a = alpha;
my $b = NATO('B');
say $a; # ↪︎ alpha
say $b; # ↪︎ bravo
say $a.value; # ↪︎ A
say $b.value; # ↪︎ B
Besides using EVAL and given a Str that corresponds to one of the enums, how could I create $c to be an enum value equivalent to charlie?
my $x = 'charlie';
my $c = ...
You can treat it as a Hash:
my $c = NATO::{$x};
You can use indirect name lookup:
enum NATO (:alpha<A>, :bravo<B>, :charlie<C>);
my $x = 'charlie';
my $c = ::($x);
say $c.value;
I need to perform the same operations on several different associative arrays in bash. Thus, I'd like to use functions to avoid code duplication. However, I'm having troubles accessing the data inside the function. Here's a minimalistic example:
#!/bin/bash
# this function works fine
function setValue() {
# $1 array name
# $2 array index
# $3 new value
declare -g $1[$2]=$3
}
# this function doesn't
function echoValue() {
# $1 array name
# $2 array index
echo ${$1[$2]}
}
declare -A arr1=( [v1]=12 [v2]=31 )
setValue arr1 v1 55
echoValue arr1 v2
I've tried ${$1[$2]}, ${!1[!2]} and all other possible combinations, but none of these work. How can I access these values with BOTH array name and index being dynamic rather than hard-coded? I'd be grateful for any advice here.
The array name and index together are needed for indirect parameter expansion.
echoValue () {
# $1 array name
# $2 array index
t="$1[$2]"
echo "${!t}"
}
In Bash, variables that are being declared outside of a function, can be used as Global Variables. That means you can call/access them from inside a bash function, without the need to passing variables as arguments inside the function.
an example:
#!/bin/bash
function setValue() {
arr1[v1]=55
}
function echoValue() {
echo ${arr1[v2]}
}
declare -A arr1=( [v1]=12 [v2]=31 )
setValue
echoValue
echo ${arr1[*]}
The output is :
31
31 55
I would suggest to take a look on this Bash Variable Tutorial
Another solution
function echovalue()
{
local str
str="echo "'$'"{$1""[$2]}"
eval $str
}
Is it possible to get logs generated by one function in variable without returning that value from that function in TCL like what "$" used to be do in BASH.
function f1 {
echo "ABC"
return 0
}
Calling procedure is,
var=$(f1) ;# gives output ABC
What i know about how to solve this problem is,
proc f1 {} {
return "ABC | 0"
}
At the time of calling i need extract both value like,
set console_msg [lindex [split [f1] "|"] 0]
set retval [lindex [split [f1] "|"] 1]
Is there a proper way to do it in TCL?
Thanks,
This may seem obvious to you in hindsight:
set value [f1]
and to assign to variables:
lassign [split $value |] msg val
how to pass 2d array to function in shell script ?
i need to pass matrix to function but it do not work
tr(){
matrix="$3"
num_rows="$1"
num_columns="$2"
f1="%$((${#num_rows}+1))s"
f2=" %9s"
for ((i=1;i<=num_rows;i++)) do
for ((j=1;j<=num_columns;j++)) do
echo -ne "${matrix[$i,$j]}\t"
done
echo -e "\n"
done
tr $rows $columns $x
Use an associative array:
declare -A matrix
Then things like matrix[6,7]=42 will work because "6,7" ist just a string, and associative arrays accept strings as indices. You might as well write things like
matrix[one,two]=three
matrix[yet,another,dimension]="Perry Rhodan"
You can just write any string between [ and ]. Here is a complete example for how to use it.
#!/bin/bash
#
# Example for a function that accepts the name of an associative array ...
# ... and does some work on the array entries, e.g. compute their sum
# We assume that all *values* of the array are integers - no error check
sum() {
local s=0 # we don't want to interfere with any other s
declare -n local var="$1" # now var references the variable named in $1
for value in "${var[#]}" # value runs through all values of the array
do
let s+="$value"
done
echo sum is $s
}
declare -A m # now m is an associative array, accepting any kind of index
m[0,0]=4 # this looks like 2-dimensional indexing, but is is not
m[2,3]=5 # m will accept any reasonable string as an array index
m[678]=6 # m does not care about the number of commas between numbers
m[foo]=7 # m does not even care about the indices being numbers at all
sum m
As you see, the matrix m not really has 2 dimensions. It just takes any string as an index, as long as it does not contains certain shell syntax characters, and comma is allowed in the string.
Please note the reference declare -n ... - this allows simple access to the matrix from within the function and, most important, without knowing the name of the matrix. Thus you can call that function for several matrices with different names.
The keyword local is important. It means that, upon return, var is unset automatically. Otherwise you will have a reference "var" to an associative array. If you ever want to use var later, it will be hard to use it because you cannot use it as anything else but an associative array. And if you try to get rid of it by "unset var", bash will kindly remember that var refers to m, and delete your matrix m instead. In general, make variables in functions be local wherever possible. It even allows me to re-use a name. For example, using "s" as a variable name inside a function may appear dangerous because it might change the value of a global variable "s". But it doesn't - by declaring it local, the function has its own private variable s, and any s that might already exist is untouched.
Just as a demonstration: If you want to see the array indices in the loop, do this:
sum() {
local s=0 # we don't want to interfere with any other s
declare -n local var="$1" # now var references the variable named in $1
for i in "${!var[#]}" # !var means that we run through all indices
do # we really need a reference here because ...
let s+=${var["$i"]} # ... indirections like ${!$1[$i]} won't work
done
echo sum is $s
}
How do you initialize an array in expect-send script? We can initialize a variable using
set Variable_name value. Likewise how can an array be initiated in expect-send script?
I assume you mean array as in associative array, not array as in C-like numerically-indexed list. You use the array set command:
array set varname {key1 val1 key2 val2 key3 val3 ... ...}
Since the contents of braces are not evaluated by Tcl (hence by expect), you can make it pretty if you want
array set varname {
key1 val1
key2 val2
.... ....
}
You can also assign the array elements directly:
set varname(key1) val1
set varname(key2) val2
...
Note that unlike set used to set a variable, array set works differently:
In the same tclsh:
% array set a {key1 val1 key2 val2}
% parray a
a(key1) = val1
a(key2) = val2
#This will not delete the content of the array:
% array set a {}
% parray a
a(key1) = val1
a(key2) = val2
#This will add new key-value pair:
% array set a {key3 val3}
% parray a
a(key1) = val1
a(key2) = val2
a(key3) = val3
#Array keys are unique:
% array set a {key1 val1 key2 val2}
% parray a
a(key1) = val1
a(key2) = val2
a(key3) = val3
#To unset the entire array content:
array unset a *
#To unset the array:
array unset a