LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
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


Reply
  Search this Thread
Old 06-20-2012, 06:22 PM   #1
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Rep: Reputation: Disabled
Question "for and while looping" questions


I have been trying to come up with a program that can do this:
Say I have a file named "sire" with a single field;
10
229
288
35
83
47
3
I want to create a file "gen" with three fields with the data in file "sire" listed in field 1 while field 2 and 3 are just 1 each like this:
10 1 1
229 1 1
288 1 1
etc
I want to use this to solve an equation of the form "itgen -m 500 -r gen b beta -n inverseNRM
-m 500 indicates the number of rounds to iterate
-r gen is the right hand side of the equation
-b beta is the filename for the solution
-n inverseNRM is another file with three fields.

Really need help here. Thanks
 
Old 06-20-2012, 06:27 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
sed 's/$/ 1 1/' sire > gen

... and it's NOT urgent to any of us; please don't be rude,
we're all volunteers here, donating our precious spare time.
 
Old 06-20-2012, 06:34 PM   #3
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Original Poster
Rep: Reputation: Disabled
I never intended to be rude. I was told the title of my first post was inappropriate and I was to use something like urgent and name of program which I just did.
Its important to me, sorry if I offended you

Last edited by iconig; 06-20-2012 at 06:35 PM.
 
Old 06-20-2012, 09:09 PM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Interesting .. who told you that?

:)

That aside - did the sed command do the trick for you?



Cheers,
Tink
 
Old 06-25-2012, 02:04 PM   #5
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Original Poster
Rep: Reputation: Disabled
the sed gave me a file with three fields which is a step. I am actually trying to run a while loop such that it reads every line and it uses each line to do a command ("itgen -m 500 -r gen b beta -n inverseNRM) which I saved in a file called perm. It should output each result for each line after doing the command. I tried using something like this:

IFS=$'\n';for line in `cat gen`; do ./perm ${line} > ${line}; done.

When I did this, it said permission denied, although it gave me each line of gen, there was no content.
I am a little new in programing, I will appreciate some help thank you
 
Old 06-25-2012, 04:44 PM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,252

Rep: Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685Reputation: 2685
So you wrote that line at the command prompt or this is inside yet another file?

Also, is the perm file executable and have the interpreter (maybe bash) set at the top?

I think you need to fill in some more blanks before we can assist.
 
Old 06-25-2012, 04:46 PM   #7
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
I must say I don't quite understand how the initial request and the
itgen -m 500 -r gen b beta -n inverseNRM
hang together ... irrespective of the content of the line you wish
to run the same command over and over?
\
How does the BOLD bit above hang together w/ ./perm?


Can you give us a fleshed out example of input, and the desired
effect, plus the expected output?
 
Old 06-25-2012, 05:45 PM   #8
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Original Poster
Rep: Reputation: Disabled
I used IFS=$'\n';for line in `cat gen`; do ./perm ${line} > ${line}; done on the command prompt. I saved itgen -m 500 -r gen b beta -n inverseNRM in a file called perm. The content of perm is an equation I want to solve. Its like gen X beta= inverseNRM, then beta= gen-1 X inverseNRM. But that is a different program on my computer. inverseNRM is another file

Last edited by iconig; 06-25-2012 at 05:57 PM.
 
Old 07-11-2012, 12:47 PM   #9
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Original Poster
Rep: Reputation: Disabled
how to read each file in a directory and pass each file separately into a do command

Code:
I have been trying to read files in a directory then pass it to a command so that each file gets processed in the do command and the output after the command gets stored separately file by file.
I have this directory:
Code:
home/pro/connection
The files in the directory connection are names:
S1:
Code:
21 3 2
S2
Code:
20 1 2
Code:
I want to loop through each file and send each file to be processed in the do command, then the result of each file processed gets saved differently and each gets moved into one folder.
Something like this:

Code:
#!/bin/bash
i=1
FILES=/home/pro/connection/*
for f in $FILES
do 
eacho "Processing of $f file...:# take action on each file. $f store current file name
cat $f | command # output from this command for S1 is beta >> beta >> beta.$i # so file S1 and S2 have outputs beta1 and beta2
done
Code:
can I use while command for this as well?
Code:
Is it possible to create S1 and S2 without having to output them just create them and send them separately to the do command? The final output (beta1 and beta2) are more important than outputting files S1 and S2 (though I need them to get sent to the do command)
Thanks
 
Old 07-11-2012, 01:11 PM   #10
Farzan Mufti
LQ Newbie
 
Registered: Feb 2007
Location: USA/Canada
Distribution: Red Hat, CentOS, Scientific, Fedora, Ubuntu, SUSE, SLES
Posts: 14

Rep: Reputation: 6
Linux, Bash Script

You can certainly use while, however, for .. do .. done is, IMHO, a better approach. So your code should look something like

#/bin/bash
DIRECTORY=/home/pro/connection
OUTPUT_FILE=$DIRECTORY/out.txt
#Please choose a command
#COMMAND=something
COMMAND='ls -l'
for f in $DIRECTORY/*
do
echo "Processing file $f"
#Applying this command onto each file separately
#And redirecting (appending) to an output file
$COMMAND $f >> $OUTPUT_FILE
done

If you want to create files without redirection, you can simply use the touch command
touch afile bfile

For details of this command you can check the man pages
man touch


Kindly elaborate if you have any more questions and I would be glad to assist.

Regards,
Farzan Mufti

Last edited by Farzan Mufti; 07-13-2012 at 01:17 PM.
 
Old 07-11-2012, 01:50 PM   #11
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Please use ***[code][/code] tags*** around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, bolding, colors, or other fancy formatting.

And iconig, please use them only for code and data. Don't put them around the explanation text. I can hardly read your post.

Code:
for f in $(ls $DIRECTORY)
No, no no. Don't read lines with for, and don't parse ls! Use simple globbing instead:

Code:
for f in $DIRECTORY/*; do
Code:
COMMAND='ls -l'
Again, no, no, no. Variables are for storing data, not code. Use a function.

I'm trying to put a command in a variable, but the complex cases always fail!
http://mywiki.wooledge.org/BashFAQ/050


This is incorrect too:
Code:
FILES=/home/pro/connection/*
Don't use a single variable for storing lists of things, like files. If you don't want to loop over them directly, as above, use an array.


Here are a few useful bash scripting references:
http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
http://wiki.bash-hackers.org/scripting/newbie_traps
http://www.linuxcommand.org/index.php
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/index.html
http://www.gnu.org/software/bash/manual/bashref.html
http://wiki.bash-hackers.org/start
http://ss64.com/bash/

Start with the first one, the BashGuide. It will explain all the basic features of bash scripting.

Last edited by David the H.; 07-11-2012 at 01:57 PM. Reason: fix & link addition
 
1 members found this post helpful.
Old 07-12-2012, 06:58 AM   #12
Farzan Mufti
LQ Newbie
 
Registered: Feb 2007
Location: USA/Canada
Distribution: Red Hat, CentOS, Scientific, Fedora, Ubuntu, SUSE, SLES
Posts: 14

Rep: Reputation: 6
Bash scripting

Well,
In advanced shell scripting variables ARE used to store commands also. It makes the code a lot more readable.

There is simply nothing wrong with
Code:
FILES=/home/pro/connection/*
It is very common in Bash scripting to do this and has no problem with it. There is no "no no" to it, period. It is not wrong because first, it runs in Bash and second, it is not a bad practice. Bash for statement works fine with it and making it an array is needless.

for f in $DIRECTORY/*

would be good.
If you want to get file list of the current directory, you can do like
Code:
for f in *
do

Last edited by Farzan Mufti; 07-13-2012 at 01:06 PM.
 
Old 07-12-2012, 12:16 PM   #13
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
I completely disagree with you, and so do all the very smart people at the wooledge site and others. You should always use the right tool for the right job.

Contrary to your assertion, putting the command in a variable obscures what's being run. It blurs the line between data and code. Not to mention that the shell parsing rules make it tricky-to-impossible to handle special characters like spaces inside them. Again, variables are for data (or at most arguments to commands), and functions are for code.

As for arrays, a scalar variable holds a single value, and you'd have to rely on shell word-splitting or other unreliable splitting techniques to extract multiple entries from them. But arrays are specifically designed for storing and operating on multiple entries of related values. They are particularly suited for working with lists of filenames, in cases where you can't just loop over them directly.

Actually, I do have to apologize in regards to my initial criticism. globs don't expand in "var=value" lines, so actually this is acceptable:
Code:
FILES=/home/pro/connection/*
for f in $FILES
"$FILES" expands into the globbing pattern, and the pattern then expands into a list of files that the for loop can safely accept. The variable never actually contains the file list itself.

But as for "for f in $(ls directory)", I say it again, and even louder...NO, NO, NO, NO, NO! The for loop is simply not designed for processing the output from commands like ls or cat. Read the link I gave carefully and please do not ever suggest it again. I'm serious. The only time it is acceptable is when you use a command that outputs discreet values that are not affected by word-splitting and globbing expansion, such as seq.
 
Old 07-12-2012, 03:37 PM   #14
iconig
LQ Newbie
 
Registered: May 2012
Posts: 28

Original Poster
Rep: Reputation: Disabled
well either of your suggestion is not doing what I need, I would like each file to be processed by the program
Code:
itgen -m 500 -r rhs -b beta -n inv
The each file is supposed to be opened and read as rhs, then the output file from each line with this command is beta, so I will have
Code:
beta.1, beta.2 etc
 
Old 07-12-2012, 04:15 PM   #15
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
I took the liberty to merge your two very closely related threads, and would
ask that you stick with one thread per topic in the future.


Cheers,
Tink
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Could someone help me with looping in vb cobrien Programming 9 11-12-2010 09:17 AM
looping images? Cording44 Linux - Newbie 1 05-05-2009 10:34 AM
Help with looping more than 1 variable. hdoyle Linux - Newbie 4 01-22-2009 06:28 AM
Not able to do looping in linux Amey Joshi Linux - Newbie 7 08-13-2008 04:25 AM
login looping plaircpa Slackware 3 10-31-2005 09:10 PM


All times are GMT -5. The time now is 06:23 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration