LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
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-02-2008, 03:37 PM   #1
handband2
LQ Newbie
 
Registered: Nov 2008
Posts: 6

Rep: Reputation: 0
Loop column output


I need help in what to do with a bash script? I'm trying to run a command to output the data from a table and then insert it into commands. Looping for each row of data.

For example the output data from a table:

10 John house
20 Jane apt
30 Joe townhome


Then I need to take the output from the data and insert it into another command, so for example my output would look like:


-----
The number of the person is 10
The name of the person is John
John lives in a house
-----
The number of the person is 20
The name of the person is Jane
Jane lives in a apt
-----
The number of the person is 30
The name of the person is Joe
Joe lives in a townhome


Can anyone help or point me where to go on how to do this?

Thanks!
 
Old 11-02-2008, 05:22 PM   #2
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,269

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
Well, you could look here:
http://www.tldp.org/LDP/abs/html/
Hint, you can set the IFS variable to just a newline and then cat the file line by line.
There are of course other ways...

HTH
http://catb.org/~esr/faqs/smart-questions.html
 
Old 11-02-2008, 08:18 PM   #3
handband2
LQ Newbie
 
Registered: Nov 2008
Posts: 6

Original Poster
Rep: Reputation: 0
More information

The code I have is:
Code:
#!/bin/bash

echo
echo "-----------------------------------------------------------------"

DATA=`cat data.txt`

for i in $DATA; do

	NUM=$(echo $i |awk '{print $1}');
	NAME=$(echo $i |awk '{print $2}');
	LOC=$(echo $i |awk '{print $3}');	

	echo "The number of the person is $NUM"
	echo "The name of the person is $NAME"
	echo "$NAME lives in a $LOC"

echo
echo "-----------------------------------------------------------------"
echo
done
The output is:
Code:
-----------------------------------------------------------------

The number of the person is 10
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is John
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is house
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is 20
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is Jane
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is apt
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is 30
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is Joe
The name of the person is 
 lives in a 

-----------------------------------------------------------------


The number of the person is townhome
The name of the person is 
 lives in a 

----------------------------------------------------------------
How can I get the output to look like:
Code:
-----
The number of the person is 10
The name of the person is John
John lives in a house
-----
The number of the person is 20
The name of the person is Jane
Jane lives in a apt
-----
The number of the person is 30
The name of the person is Joe
Joe lives in a townhome
Thanks!
 
Old 11-02-2008, 11:16 PM   #4
darkbolt
LQ Newbie
 
Registered: Sep 2005
Distribution: Gentoo, Debian, FreeBSD
Posts: 3

Rep: Reputation: 0
Solution in python.

Code:
#/usr/bin/env python

source = '10 John house\n20 Jane apt\n30 Joe townhom'
for line in source.split('\n'):
    segments = line.split()
    print "The number of the person is " + segments[0] + '\n'
    print "The name of the person is " + segments[1] + '\n'
    print segments[1] + " lives in a " + segments[2] + '\n'
 
Old 11-02-2008, 11:21 PM   #5
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,269

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
As I said, look up how to set the IFS variable. By default, its newline, tab, space (ie any/all of these) which means when you cat a file like yours you get each non-whitespace value separately, which messes up your program.
If you set it to a newline only, then you can split each record and print it out as you wish.
Do the cat in the for... line, not separately.
 
Old 11-03-2008, 10:42 AM   #6
handband2
LQ Newbie
 
Registered: Nov 2008
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by chrism01 View Post
As I said, look up how to set the IFS variable. By default, its newline, tab, space (ie any/all of these) which means when you cat a file like yours you get each non-whitespace value separately, which messes up your program.
If you set it to a newline only, then you can split each record and print it out as you wish.
Do the cat in the for... line, not separately.
chrism01,

Thanks!! I got it working by doing the following:
Code:
#!/bin/bash

IFS='
'

echo
echo "-----------------------------------------------------------------"

DATA=`cat data.txt`

for i in $DATA; do

	echo

	NUM=$(echo $i |awk '{print $1}')
	NAME=$(echo $i |awk '{print $2}')
	LOC=$(echo $i |awk '{print $3}')	

	echo "The number of the person is $NUM"
	echo "The name of the person is $NAME"
	echo "$NAME lives in a $LOC"

echo
echo "-----------------------------------------------------------------"
done
echo

Last edited by handband2; 11-03-2008 at 10:59 AM.
 
Old 11-03-2008, 12:23 PM   #7
jan61
Member
 
Registered: Jun 2008
Posts: 235

Rep: Reputation: 46
Moin,

Quote:
Originally Posted by handband2 View Post
...
Code:
...
DATA=`cat data.txt`

for i in $DATA; do
        ...
	NUM=$(echo $i |awk '{print $1}')
	NAME=$(echo $i |awk '{print $2}')
	LOC=$(echo $i |awk '{print $3}')	
        ...
done
that's a very slow and inefficient solution. You start 3 subshells and 3 extra processes for each line of your input file. There are better ways to get the variable values - for example:
Code:
while read NUM NAME LOC <data.txt; do
  # echo lines
done
This way you even don't have to redefine IFS.

Jan
 
Old 11-03-2008, 04:15 PM   #8
handband2
LQ Newbie
 
Registered: Nov 2008
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by jan61 View Post
Moin,



that's a very slow and inefficient solution. You start 3 subshells and 3 extra processes for each line of your input file. There are better ways to get the variable values - for example:
Code:
while read NUM NAME LOC <data.txt; do
  # echo lines
done
This way you even don't have to redefine IFS.

Jan
Thanks that also works!

But what if data.txt was a command to output data (for example the command top)?
 
Old 11-05-2008, 03:40 PM   #9
jan61
Member
 
Registered: Jun 2008
Posts: 235

Rep: Reputation: 46
Moin,

Quote:
Originally Posted by handband2 View Post
But what if data.txt was a command to output data (for example the command top)?
In this case use a for loop - it will separate the fields itself. If your command's output contains more than 3 fields, cut the first 3 fields:
Code:
for NUM NAME LOC in `some_command | cut -f1-3 -d" "`; do
   ...
done
Jan

EDIT: Forget the loop above - it's nonsense. I wonder if my brain was sleeping somewhere behind the moon at the time of my post %-/

A for syntax can't contain more than one variable. But there are other ways to prevent from using external commands within the loop (I try always to avoid that because of poor performance), for example:
1. Use a temporary file for the command's output
2. Split the line using shell builtins:
Code:
IFS='
'
declare -a my_arr
for line in `some_command`; do
  OLD_IFS="$IFS"
  IFS=" "
  my_arr=($line)
  NUM=${my_arr[0]}
  NAME=${my_arr[1]}
  LOC=${my_arr[2]}
  IFS="$OLD_IFS"
done

Last edited by jan61; 11-06-2008 at 07:51 AM.
 
  


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
LXer: Using Bash To Feed Command Output To A While Loop Without Using Pipes! LXer Syndicated Linux News 0 08-06-2008 12:10 PM
How can we config to display facility/priority column in syslog output (RHELAS 4) LiXin Linux - Server 5 04-30-2008 11:09 AM
Bash loop using output of grep not working as needed Jim Pye Programming 7 01-16-2008 10:27 PM
command to sort by floats in fourth column of standard output jhwilliams Linux - Software 4 06-22-2007 01:27 PM
Sorting of multi-column output rytrom Linux - Newbie 11 09-15-2003 11:31 AM


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

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration