I am attempting to take a file and store the items from the file into an associative array in bash. An associative array might not be the best course for my action, but from my research it appears to be a good fit. I have a file that looks like the following:
personid
phone
phone
phone
personid
phone
phone
phone
Please note, persionid is always 20 digits, and phone is always 10. There is nothing else in this file, and no whitespace, just one of these per line. I wanted to map these to an associative array with my key being personid and my value being phone.
The code I've worked on regarding this piece is the following:
declare -A person
while read key; do
if [ ${#key} -eq 20 ] ; then
personID="$key"
else
phone="$key"
fi
person=( ["$personID"]="$phone" )
done < myFile.txt
for i in "${!person[#]}"
do
echo "key: $i"
echo "value: ${person[$i]}"
done
It will correctly store and print one personID as the key and one phone as the value....but there should be multiple values for phone. I'm thinking when I assign person, I must be doing that wrong, or have it in the wrong placed. But I've played around with it for quite sometime now and can't get it right. Never used associative arrays before, so having a little trouble. Thanks in advance for the help!
Associative arrays are no different to any other arrays in that there will always be exactly a 1:1 mapping from key (or index) to value. In your case, you want a 1:many mapping from key (personID) to values (phone numbers). One way to do this would simply to store a list of phone numbers which is effectively the "single" value mapped to a personID. You can construct your list however you like, with whitespace, or comma delimiters or anything else.
For example if you want : as your delimiter, you could do this to add each phone number to the list:
if [ -n ${person[$personID]} ] ; then
person[$personID]}="${person[$personID]}:$phone"
else
person[$personID]}="$phone"
fi
Related
I'm a beginner to bash, and I'm quite struggling with associative array. I created many associative arrays and integrated all the data by using key '0, 1, 2, 3'. Simply saying ArrayA[0], ArrayB[0], ArrayC[0].... have data on a common topic. So these keys are important to me. Now I want to make another array to access these keys, and I want the keys of the new arrays to be the data of the related keys. For example,
declare -A NewArray
ArrayA[0]=3
ArrayB[0]=4
ArrayC[0]=6
NewArray[ArrayA[0]+ArrayB[0]+ArrayC[0]]=0
so that it could be NewArray[346]=0 or NewArray[3,4,6]=0. Any helps would be so much appreciated, I've been thinking about this for hours.
Bash has no concatenation operator as it doesn't need any.
NewArray[${ArrayA[0]}${ArrayB[0]}${ArrayC[0]}]=0
echo ${NewArray[346]}
or
NewArray[${ArrayA[0]},${ArrayB[0]},${ArrayC[0]}]=0
echo ${NewArray[3,4,6]}
I'm scripting in Bash.
I have an issue with my associative array, when I put a record in my array like that:
declare -A arr_list_people_name
The way I put text in my associative array in a loop (put text sorted) :
arr_list_people_name[$peopleId]+=$peopleName
The way I read my array:
for KEY in "${!arr_list_people_name[#]}"; do
# Print the KEY value
echo "Key: $KEY"
# Print the VALUE attached to that KEY
echo "Value: ${arr_list_people_name[$KEY]}"
done
My list is not in the same order compare to the way I recorded it. However, I d like to find the same order than the way I recorded it in my array (sorted by value or key).
Do you have any idea how to manage that ?
You need to use a second, indexed array to store the keys in the order you add them to arr_list_people_name.
...
arr_list_people_name[$peopleId]+=$peopleName
arr_order+=("$peopleId")
...
for id in "${arr_order[#]}"; do
echo "Key: $id"
echo "Value: ${arr_list_people_name[$id]}"
done
I'm trying to use perl to find the number of periods on a line and if it contains the number I have defined then to group portions of a line together.
Here is what I have so far
if (($lines [0] =~ /./) ==3){
$lines [3] = $lines [0][3..-1]
if ($lines [2] =~ /'get'/);
print Output "qa;$lines[2];get\n"
I feel like I'm close buy not close enough.
Here is a sample of the text file I am reading from, but what I have is not matching.
...State [ ]
.....County [ ]
.......City [ get set clear ]
.......ZIP [ get detail ]
The goal is for the output to look something like this when I'm done. I really only want get commands right now.
qa;State;County;City get
But I can't seem to get it to match the periods. Any help would be awesome.
You're not really that close, actually. Here are some pointers to get you in the right direction:
m// does not return how many times a match was found. In scalar context (like comparing it to a number as you are), it returns true or false, depending on whether a single match was found at all.
In a list context, the m// would return all the matches, but you'd still need to assign that list to an array and then find the size of the array, in order to get a count of all the matches
you need to escape the period in the pattern match, as that is a special character
Strings are not character arrays. You cannot refer to $lines[3] as though it's an array of characters by putting another set of [ ] subscripts on the end. There are functions that help you get pieces of strings. Look into substr, for example. (And even if it was, [3..-1] would not be a valid subscript, even though -1 does represent the last index of an array)
Get rid of the single quotes in the second pattern match. That's saying you literally want to look for the string: single quote, g, e, t, single quote.
Good luck to you!
Sadly I don't know the exact word for what my problem is, but I try to explain it and I'd be happy if someone could tell me what I should be looking for :)
I have two arrays
Array 1 with Name, Surname, and Array 2 with Name, Surname aswell.
Of course, Surnames and Names are NOT unique, but the combination of them is unique.
So now I'd need to check if the Combination of Array 1 IS existing in Array 2, if not do something...
Now my problem is that i know -contains but I don't know how to use that on multiple hashes (Contains Surname or Name only is not useful, it has to be and)
i tried the following
if ( $oldList -notcontains $newPerson.Name -and $newPerson.Surname) {....}
But it neither worked nor I expected it to work or I did another mistake?!
Could anybody give me some advice? Thanks in advance
PS. It is not Surname/Name in my case, but I for understanding Surname/Name is easier!
Update
The Hashtables (or Arrays?!) look with an Write-Host like this:
#{Name=Peter; Surname=Fox}.... and so on
Update 2 - Solution
Hey Guys, just for every future reader who maybe doesn't find out by himself...
It's an Compare-Object $arr1 $arr2 - and it outputs every diffenence by either => odr =<
:) Therefore question is answered (by myself :P)
Compare-Object $arr1 $arr2
delivers the solution I was looking for. It shows differences by => and <= and therefore you can evaluate if it is containd in arr2 or not.
I've pushed the results of my DBI query into the Array of Hashes and called a subroutine with these AoH's as an input (the same subroutine with different AoH's). As I don't know the exact size of my AoH, I'd like to determine it dynamically. Is there any way to get the number of fields/columns in the AoH?
Something like scalar #inContent, but I need the horizontal size only.
According to the actual size of AoH, I'd like to iterate it and read its content. At the moment I address fields by name, but it may vary from AoH to AoH, so it's not a very effective solution:
foreach my $row (#inContent) {
print $row->{ID}; }
but would like to get something like that:
print $row->[0]->value;
Thank you for your help in advance.
The number of keys in the first hash in the array is
scalar keys %{$inContent[0]}
and the rest of them should have the same set of keys since it's a DBI query, so it's a good measure of "horizontal size".