Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place! |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
03-17-2011, 06:47 PM
|
#1
|
|
LQ Newbie
Registered: Mar 2011
Posts: 3
Rep:
|
Passing a list of variables to a for loop
Hi, I'm trying to do substitutions to a file based on passed variables. For example, I have a file called test.txt that has 5 lines:
cond0
cond1 or cond0
cond2
cond4
cond0
What I want to do is to go through that file, line by line and check for the presence of a passed variable in that line. If I have a match, then substitute and print, otherwise print line as is. My problem arises in that the number of variables is well, variable. The code I started with was the following:
passed variables were: earth wind fire
Code:
args=("$@")
for ((i=0 ; i < $# ; i++ ))
do
gawk -v cin="cond${i}" -v cout="${args[i]}" '{gsub(cin,cout);print $0}" >> test.out
done
What I was hoping for was test.out to look like this:
earth
wind or earth
fire
cond4
earth
What I get is a much longer file like this:
earth
cond1 or earth
cond2
...
This makes sense after thinking about it but is there anyway to get an output like the first case? Any help would be appreciated!
Dan
|
|
|
|
03-17-2011, 08:33 PM
|
#2
|
|
Senior Member
Registered: Oct 2003
Location: Bonaire
Distribution: Debian Etch/Lenny/Squeeze
Posts: 3,796
|
Quote:
Originally Posted by pdr_dan
Code:
args=("$@")
for ((i=0 ; i < $# ; i++ ))
do
gawk -v cin="cond${i}" -v cout="${args[i]}" '{gsub(cin,cout);print $0}" >> test.out
done
|
Are you sure $args[i] should not read $args[$i]?
Furthermore, run your script using sh -x yourscript, you'll see all values of your variables, and see if $i is being substituted correctly.
jlinkels
|
|
|
|
03-18-2011, 01:38 PM
|
#3
|
|
LQ Newbie
Registered: Mar 2011
Posts: 3
Original Poster
Rep:
|
Thanks for your reply jlinkels, and the info about "sh" that will make my life easier. The actual substitution works fine, the problem is more of a logical one. Given that I don't know the number of variables to be passed, is there anyway to do the substitution in a loop (or whatever) that doesn't generate repeats. For instance, the way I have it set up now (and btw, there was an error in the original code, the gawk line should have had the test.txt input file before the test.out output file), it goes through the file once for each variable and substitutes for that variable. This ends up generating an output file 3X longer than the input file, eg
earth
cond1 or earth
cond2
cond4
earth *then the next variable is checked
cond0
wind or cond0
cond2
cond4
cond0 *then the third would be checked
cond0
cond1 or cond0
fire
cond4
cond0
I can't think of a way to do a single pass with all the variables IF you don't know how many variables there are beforehand. There probably won't be more than 5 variables so I guess I could do something clunky like using a case statement to check the number of variables and execute a specific substitution statement depending on the number. Seems like there should be a better way but I can't think of one.
|
|
|
|
03-18-2011, 02:49 PM
|
#4
|
|
Senior Member
Registered: Nov 2007
Location: Somewhere on my hard drive...
Distribution: Arch
Posts: 2,040
|
Yo,
Okay, fist off, I HOPE to add something sensible to this, if not do tell me...I want to learn, this is one of my ways to do just that
Is that PERL? If so, add the "satisfying" result to a string after checking if it's not already in there...
My PERL stinks (sorry) but my logical lego blocks are still there
Quote:
if (rindex($results,$incomming)!=-1)
{
print 'match';
} else
{
print 'no match';
$results = $results . $incomming;
}
|
And hey, if I'm off-topic here, just say so...it's okay
Thor
Sources:
http://www.devdaily.com/perl/edu/art...pl010003.shtml
and
http://www.tutorialspoint.com/perl/perl_rindex.htm
|
|
|
|
03-19-2011, 02:02 AM
|
#5
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,314
|
So I see a couple of problems, the biggest you have is that gawk does not make changes to a file and since you are appending all changes to the same test.out it will only ever get
longer with each growing change. Also, looking at your code I believe there are typos and missing pieces as what you have shown would never work (I refer here to the gawk line that
has no input file and the actions start with a single quote but end in a double??
That aside, I see at least 2 obvious solutions:
1. Do the whole thing in gawk and place your changes in their own file (ie the words to pass in earth and so on)
2. Use sed to make the changes to the original file on each iteration
My preference would be sed:
Code:
#!/bin/bash
cp test.txt test.out
for arg
do
sed -i "s/cond$((i++))/$arg/g" test.out
done
Quote:
|
Are you sure $args[i] should not read $args[$i]?
|
@jinkels - Yes the 'i' does not require quoting when used as an index for an array (numeric only of course)
|
|
|
|
03-21-2011, 12:38 PM
|
#6
|
|
LQ Newbie
Registered: Mar 2011
Posts: 3
Original Poster
Rep:
|
that did it, thanks everyone for your input!
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 12:07 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|