LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-03-2009, 08:50 AM   #1
relikwie
LQ Newbie
 
Registered: Sep 2009
Posts: 5

Rep: Reputation: 0
using of arrays in loops


Hi, need to process files within multiple directories and transfer these to a remote server. What I had in mind was to use arrays for this; code pasted below (explains it better):

Code:
#set the arrays
array_A=( fileA* pathtodestA hostA passwordA )
array_B=( fileB* pathtodestB hostB passwordB )
array_c=( fileC* pathtodestC hostC passwordC )

# set variables within the loop with elements from each array at the time
# and call an ftp function with the variables as arguments
for arrays in array_A array_B array_C ; do

# this is where I get stuck
file=${arrays[0]} 
path=${arrays[1]} 
host=${arrays[2]}
user=${arrays[3]}
pass=${arrays[3]}

# call ftp function
transfer_func $file $path $host $user $pass
So actually handle each array at a time.

I'am fairly new to this and guess my approach doesn't make any sense at all.

Hope someone can help me with this?

regards, relikwie
 
Old 09-03-2009, 11:12 AM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
AFAIK, you can't directly use variables inside the names of other variables. You have to use indirect methods, such as "eval" to create them.

I don't know if this is a "proper" way to do it, but it does seem to work:
Code:
#!/bin/bash

array_A=( fileA* pathtodestA hostA passwordA )
array_B=( fileB* pathtodestB hostB passwordB )
array_C=( fileC* pathtodestC hostC passwordC )


for x in A B C ; do

x='${array_'${x}

eval file="${x}[0]}"
eval path="${x}[1]}"
eval host="${x}[2]}"
eval user="${x}[3]}"
eval pass="${x}[3]}"

echo
echo array = "${x}}"
echo
echo "file = $file"
echo "path = $path"
echo "host = $host"
echo "user = $user"
echo "password = $pass"

done
There are probably better ways to go about it, perhaps with indirect variable referencing.

PS: please be careful about posting multiple threads. Ask the moderators to delete any duplicates (use the report button).
 
Old 09-03-2009, 11:40 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
By the way, even better, if possible, would be to move the setting of the array to inside the loop along with the rest of it. Then you'd only need to use one array at a time. If the each input is a line in a file, for example:
Code:
while read inputstring ; do

array=( $(echo $inputstring)  ) 

file=${array[0]} 
path=${array[1]} 
host=${array[2]}
user=${array[3]}
pass=${array[3]}

done <inputfile.txt
 
Old 09-03-2009, 12:26 PM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
This thread is a duplicate of scripting-strings-752102
 
Old 09-04-2009, 03:43 AM   #5
relikwie
LQ Newbie
 
Registered: Sep 2009
Posts: 5

Original Poster
Rep: Reputation: 0
Hi guys, thanks for the replies.

I wasn't aware of any doublepost, must have happened while hitting the back and forward button of my browser. sorry about that.


catkin, I have tried using your version which should look like this:

Code:
#set the arrays

files=( file1,     file2,     file3 )
paths=( path1,     path2,     path3 )
hosts=( host1,     host2,     host3 )
passwords=( password1,  password2,      password3 )
index_max=3


for (( index=1; index >= 3; index++ ))
do
    echo  ${files[$index]} ${paths[$index]} ${hosts[$index]} ${users[$index]} ${passwords[$index]}
done
for some reason it doesn't work. i'll go and try to grasp what you guys have put up. and hopefully I can figure this out on my own

it's appreciated!
 
Old 09-04-2009, 04:15 AM   #6
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by relikwie View Post
for some reason it doesn't work. i'll go and try to grasp what you guys have put up. and hopefully I can figure this out on my own
Some (maybe) useful notes:
1. arrays in bash are 0-based
2. array's element separator in array assignment is $IFS, not comma
3. also there is an error in the C-style for-loop definition.
Maybe this works (check the differences to see the flaws):
Code:
#!/bin/bash
files=( file1     file2     file3 )
paths=( path1     path2     path3 )
hosts=( host1     host2     host3 )
passwords=( password1  password2      password3 )

for (( index=0; index <= 2; index++ ))
do
    echo  ${files[$index]} ${paths[$index]} ${hosts[$index]} ${users[$index]} ${passwords[$index]}
done
 
Old 09-04-2009, 05:29 AM   #7
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by colucix View Post
Some (maybe) useful notes:
1. arrays in bash are 0-based
2. array's element separator in array assignment is $IFS, not comma
3. also there is an error in the C-style for-loop definition.
Maybe this works (check the differences to see the flaws):
Code:
#!/bin/bash
files=( file1     file2     file3 )
paths=( path1     path2     path3 )
hosts=( host1     host2     host3 )
passwords=( password1  password2      password3 )

for (( index=0; index <= 2; index++ ))
do
    echo  ${files[$index]} ${paths[$index]} ${hosts[$index]} ${users[$index]} ${passwords[$index]}
done
Oops Thanks for correcting my errors, colucix Test, test, test!
 
Old 09-05-2009, 01:57 AM   #8
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
colucix and catkin have already made the proper explanations but just in case this will also help...

# list.txt

Code:
"fileA" "pathtodestA" "hostA" "userA" "passwordA"
"fileB" "pathtodestB" "hostB" "userB" "passwordB"
"fileC" "pathtodestC" "hostC" "userC" "passwordC"
# script.sh

Code:
IFS=$' \t\n'  # normal IFS

while read -u 4 LINE; do
    # these are just optional.  you can directly access the variables if you want

    set -- $LINE  # or eval "set -- $LINE"
    file=$1 path=$2 host=$3 user=$4 pass=$5

    # or

    array=($LINE)
    file=${array[0]} path=${array[1]} host=${array[2]} user=${array[3]} pass=${array[4]}

    # do the work here
    : ...

    # optionally ask user for an input before continuing to the next
    : echo press any key to continue
    : read -n1  # please check if -n1 is the proper option
done 4< list.txt

Last edited by konsolebox; 09-05-2009 at 02:01 AM. Reason: code
 
Old 09-05-2009, 11:56 AM   #9
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
In cases like this, I find I can usually pipe lines to a loop and cut them, which is almost always straight-forward and easily reproducible:
Code:
specs_A='fileA*,pathtodestA,hostA,passwordA'
specs_B='fileB*,pathtodestB,hostB,passwordB'
specs_C='fileC*,pathtodestC,hostC,passwordC'

{ echo "$specs_A";
  echo "$specs_B";
  echo "$specs_C"; } | while read line; do

  file="$( echo "$line" | cut -d, -f1 )"
  path="$( echo "$line" | cut -d, -f2 )"
  host="$( echo "$line" | cut -d, -f3 )"
  user="$( echo "$line" | cut -d, -f4 )"
  pass="$( echo "$line" | cut -d, -f5 )"

  transfer_func $file $path $host $user $pass
done
This at least makes the loop independent of the source, e.g. you could just as easily put your transfers in a CSV and cat it into the loop.
Kevin Barry

Last edited by ta0kira; 09-05-2009 at 11:58 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Nested for loops and arrays in C iongrey Programming 10 04-24-2009 05:25 PM
Arrays of Structures to Arrays of Classes knobby67 Programming 1 01-01-2008 01:39 PM
Question about outputing arrays with pointers, then just arrays... RHLinuxGUY Programming 1 04-12-2006 05:40 AM
Python: Need help making a simple program using arrays and loops Baix Programming 11 08-13-2005 11:26 PM
while loops + while : blizunt7 Linux - General 3 12-04-2004 05:27 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:35 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration