LinuxQuestions.org
Visit Jeremy's Blog.
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 11-06-2008, 07:12 PM   #1
Passions
LQ Newbie
 
Registered: Mar 2007
Distribution: RHEL 5.1
Posts: 20

Rep: Reputation: 0
How do I create multiple variables from a list in Bash?


Can anyone help me out. Let's say I have a simple txt file called, girls.txt:

Janet
Harriet
Jill
Gertrude


I want to be able to assign each girl a variable. So far I have:

i=1
for names in `cat girls.txt`;do
eval list$i=$names
i=`expr $i + 1`
done

I get the correct names, when I manually enter:
echo $list1
echo $list2

But if I add "echo $list$i" it freaks out. I want to throw that into the for loop so I can just spit out all the names.

i=1
for names in `cat girls.txt`;do
eval list$i=$names
echo $list$i
i=`expr $i + 1`
done


When I execute this instead of the girls names, I get:

1
2
3
4


Any help? Thanks!!!
 
Old 11-06-2008, 07:22 PM   #2
billymayday
LQ Guru
 
Registered: Mar 2006
Location: Sydney, Australia
Distribution: Fedora, CentOS, OpenSuse, Slack, Gentoo, Debian, Arch, PCBSD
Posts: 6,678

Rep: Reputation: 122Reputation: 122
[]

So

list[1]=Janet

echo ${list[1]}

Note the {} in retrieval
 
Old 11-06-2008, 10:04 PM   #3
Kenhelm
Member
 
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 360

Rep: Reputation: 170Reputation: 170
Try:-
eval echo \$list$i
But, as billymayday has suggested, it might be better to use an array.
 
Old 11-07-2008, 11:50 AM   #4
Passions
LQ Newbie
 
Registered: Mar 2007
Distribution: RHEL 5.1
Posts: 20

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by Kenhelm View Post
Try:-
eval echo \$list$i
But, as billymayday has suggested, it might be better to use an array.
Perfect! That solved my issue. Cheers!
 
Old 05-19-2009, 03:12 AM   #5
the dsc
Member
 
Registered: May 2009
Distribution: Debian
Posts: 175
Blog Entries: 245

Rep: Reputation: 47
How can we tweak this so the variables from the list can have spaces, like:

Charlie Brown
John Stuart Mill
Steve Martin


and so on?

The way it is it gets each word as a variable, ideally it would be an entire line.


(thanks in advance.... if I make it, it will help *a lot* undeleting (with ext3grep) tons of files I've accidentally deleted... and additionally could also improve a bit a screensaver-like-wallpaper-changer script I have )
 
Old 05-19-2009, 03:53 AM   #6
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
what do you want to do actually?
 
Old 05-19-2009, 10:47 AM   #7
the dsc
Member
 
Registered: May 2009
Distribution: Debian
Posts: 175
Blog Entries: 245

Rep: Reputation: 47
I have a list of files I can potentially recover with ext3grep, which is somewhat like:

/dir/file.ext
/dir2/file with spaces in its name.ext
...

and with a script similar with this one I could replace the "echo" with something like ext3grep --restore-file /dir2/file with spaces in its name.ext

But that would require the script to somehow get the variables from lines, not just words, OR maybe I could somehow replace all the spaces by double-underlines or some unlikely character, and the script could somehow "decode" it, which would be probably even harder, I think.



This "undelete" program can theroretically "restore all", which is adequate if you have tons of files to recover and not only a few, but it's not working perfectly for me. It goes restoring for a little while, and then there's some obscure, highly-technical error which stops the process. But I still can recover files that were left behind, individually. A script with individual commands for each file would automate that for tons of files.



And, a OT warning, about the quick file listing filter on konqueror. If you filter for the filename "thrash" on a folder, and so various thrash1, thrash2, thrash3, [...] files appear, and then you select them all with control + a, and delete them, you will not be deleting just the files you're seeing selected, but all the files on the folder, and its subfolders, which were selected by control + a too, but are "hidden" from your sight. If it's a large number of files you wanted to delete, you may not even notice that the number/list is too large on the confirmation dialog... I didn't...

Last edited by the dsc; 05-19-2009 at 10:56 AM.
 
Old 05-19-2009, 01:46 PM   #8
euroquisling
LQ Newbie
 
Registered: May 2009
Distribution: Debian, Ubuntu
Posts: 10

Rep: Reputation: 1
I use this mantra, it works with any filename:

Code:
some_command_that_outputs_list | while read x; do 
 echo "$x";
 do_smth_with "$x";
done
Note the double quotes around $x, you have to have them in order to capture spaces and other weird characters in filename.

This is nice bc

1. no limitation for number of arguments, like you'd have by passing a large number of arguments to a command

2. it's as fast as shell gets
 
Old 05-21-2009, 11:59 PM   #9
the dsc
Member
 
Registered: May 2009
Distribution: Debian
Posts: 175
Blog Entries: 245

Rep: Reputation: 47
It did work, thanks

If it's not too much to ask for more, would anyone know how to do something with this same basic principle, but instead of loading an item from a list, one by one, loading, say, three lines/items, assigning each as a different variable, so, instead of "do something with x", the command would be "do something with x, do something with y, do something with z".


I'll explain why, roughly. It's ext3grep, the program I'm using. In order to recover a file, it has first to do some sort of "scan" on the partition, and saves something into a file, a sort of "report" for its own use, which will be loaded when actually restoring something. This file is loaded once for each command line, and it takes some time. Not terribly slow for a single instance, like some seconds, but if we need to do this for many, many files, it quickly adds up to days, for something that could be otherwise finished in hours :/

I think I have to add another "layer of loop" in the second script, first it would just do somewhat more or less what it does, but somehow cycling some variables, and, after having done it N times...

In some basic-like language it would be something like:



0 n=1
1 some_command_that_outputs_list | while read x; do
x=a(n)
n=n+1
if n<5 then goto 1
else
command action a(1) action a(2) action a(3) action a(4) action a(5)
goto 0



It's quite frustrating knowing more or less the logic of what have to be done, being able to layout script-like rough, but at the same time not knowing the proper syntax and substitutes for things like "goto" and line numbers :/

Last edited by the dsc; 05-22-2009 at 12:02 AM.
 
Old 05-22-2009, 12:51 AM   #10
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,369

Rep: Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753
This sounds like you need to move up to a faster, more powerful lang like Perl: http://perldoc.perl.org/
 
Old 05-22-2009, 01:41 PM   #11
Kenhelm
Member
 
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 360

Rep: Reputation: 170Reputation: 170
Try
Code:
n=1
some_command_that_outputs_list | while read a[n];do
  let n=n+1
  if [ $n -eq 6 ];then
    command action "${a[1]}" action "${a[2]}" action "${a[3]}" action "${a[4]}" action "${a[5]}"
    n=1
  fi
done
The variable 'a' is being used as a bash array.
'a[n]' is for setting the contents of the nth element of 'a'
'${a[n]}' returns the contents of the nth element of 'a'
http://tldp.org/LDP/abs/html/arrays.html
http://www.gnu.org/software/bash/man...ef.html#Arrays

If the list is in a file you can use this type of input to the loop:
n=1
while read a[n];do
...
done < filename
 
Old 05-22-2009, 07:11 PM   #12
the dsc
Member
 
Registered: May 2009
Distribution: Debian
Posts: 175
Blog Entries: 245

Rep: Reputation: 47
Thanks Kenhelm!

Unfortunately it will not be directly useful to me in this task anymore, as, differently from what I've said before, even if we give multiple commands for the same instance, it will read a file for each action/file to recover.

But maybe I'm using an older version of ext3grep, since it was (I think) the author of this program himself who gave me this tip.

Besides adding to my list of personal "how to's" on scripts, I'll give a link to this discussion on the ext3grep list, so maybe it will be useful for people with a newer version, or maybe future versions, until it's finally "GUI-fied" or "ncursed".
 
Old 05-23-2009, 05:23 PM   #13
the dsc
Member
 
Registered: May 2009
Distribution: Debian
Posts: 175
Blog Entries: 245

Rep: Reputation: 47
Me again.

Actually I've found a way to use the last script in a way that should speed things somewhat, not as fast as it would be if we could indeed restore many files loading the "stage2" file only once, like in "restore-all", but still something that could be useful until nothing better is implemented.

It's just the same script, but instead of giving the command multiple files to restore, it should give multiple independent commands.

Instead of:

ext3grep /dev/hda --restore-file ${a[1]}" --restore-file "${a[2]}" [...]

It should be:

ext3grep /dev/hda --restore-file ${a[1]}" & ext3grep /dev/hda --restore-file ${a[2]}" [...]


Theoretically it should be 2 times faster if there are two commands/instances, but eventually it should become slower by hardware/processing limits, I think, so I think it shouldn't have so many of them. I'm using about 7 or 8, I think.

I didn't really measured carefully the time gained or anything, I just have this impression by some simple, maybe imprecise tests with two simpler scripts running against a single script, with their results being saved on independent logs. Script 1a + script 1b logs had larger size than script2's log. This logic may be fundamentally flawed in some dull way that will made me ashamed of having posted it, but I think it could possibly be just like that.
 
  


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
create multiple directories in bash? Count Zero Programming 19 07-06-2008 08:34 AM
bash: random creation of multiple variables vicious1 Programming 3 04-23-2007 03:34 AM
Get strings from list using variables mwade Programming 5 10-28-2006 08:01 PM
(bash) how to list all variables? Duudson Programming 11 03-24-2005 12:35 PM
How can I get the full list of environment variables (RedHat 7.2)? yuzuohong Linux - General 1 06-07-2003 03:28 AM

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

All times are GMT -5. The time now is 05:47 AM.

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