Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
Hi there.
I'm looking to do a basic shell script whereby there are four fields in a record:
NAME
POSTALCODE
PAID
OWEDThere are about 15 records in a file that I'm reading in. I've been cutting them as follows:
#!/bin/sh
#Rent
FILE=`cat <rent_payments`while [ $EXITFLAG -eq 0 ]
doLINE=`echo $FILE | cut -f1 -d" "`
#This is supposed to stop the field at the end of each line. There's a fatal flaw in this whereby some people's names have spaces in.if [ -z $LINE ]
then
EXITFLAG=1
elseNAME=`echo $LINE | cut -d -f1`
POSTCODE=`echo $LINE | cut -d -f2`
PAID==`echo $LINE | cut -d -f3`
OWED==`echo $LINE | cut -d -f4`echo -n "Postcode: $POSTCODE Name: $NAME PAID: $PAID" >>paid
echo "" >>paidecho -n "Postcode: $POSTCODE Name: $NAME Owed: $OWED" >>owed
echo "" >>owedfi
doneThe problem is this... when the program runs, it loops forever. It does not stop. And when I ctrl-c it, the 'paid' file contains only the details from the first record and it doesn't go onto the next line.
Is there any way I can do anything about this? I've looked all over and I can't find anything! Any help would be appreciated. Thanks.

Perhaps I should have pointed out that the records look like this:
Davids,RE454JH,120,0
This is name,postcode,paid,owed. With ',' being the field delimiter.

Rather than try and fix a very broken script ;-), it would be better to use what is the right tool for this job in the first place: awk.
awk -F',' {print "Postcode: " $2 " Name: " $1 " PAID: " $3 > "paid"} {print ... > "owed"}' rent_payments
Where "..." means fill it in yourself. There is no need to write scripts for extremely simple things like this that can be done with a single command. Having said that, if the object of the exercise is to learn bash rather than solve the problem, please say so.

If I had a very large file to parse I would probably use perl:
#!/usr/bin/perl
open (FILE, "rent_payments")||die "Can't find file!";
@records=<FILE>;
foreach $line (@records){
@rent=(split(',', $line));
print "Postcode:$rent[1]...Name:$rent[0]...Paid:$rent[2]\nPostcode:$rent[1]...Name:$rent[0]...Owed:$rent[3]\n";
}

Thankyou. Perl is not an option though.
The awk command is something I had considered using but I was informed by a 'knowledgable' friend that it would be messy to do as I wanted to read records in (about 20) and then split them up into owed and paid and for the thing to tell me in descending order who owes me what. That's easy but actually cutting it is proving hard to do.
When the script runs, it always returns the first record from the file and doesn't go past the first line.
I'd rather it be a shell script and not something run from the command line as basically, all I want to do is this:
In the middle of the month, I was to see what was paid by tenants by running ./rent.
I want the script to delete any previous instances of the owed and paid files and add something to the top of each of them (echo "Paid" and echo "Owed" will suffice).
Then using the method shown in the first post, produce an ordered (in order of most owed to least owed in owed file) list of payments in two seperate files.
I've done something like this before when I used to go to college and I know it could have been done in cut but my college days are behind me now. I've looked at my older books and they're no help.
There is no object of excerise but more of proof of concept on my part.

So put the awk command in the script! It is hardly messy and you will not get your script to work at all the way it was because it is trying to process the whole file as a single variable, losing the line structure.
You could do it with cut but it is not the right way to do it - if you use script constructs properly for reading the file like read and IFS redefinition then cut is again redundant.

Hi there.
I tried the script as follows:
echo `awk -f rent_payments -F, {print "Name " $1 " Postcode: " $2 " Paid: " $3 " >rent_paid`} {print "Name: " $1 " Postcode: " $2 " Owed: " $4 >rent_arrears`} and it didn't work.
I even followed the script:awk -F',' {print "Postcode: " $2 " Name: " $1 " PAID: " $3 > "paid"} {print ... > "owed"}' rent_payments
that you gave me but I get syntax errors in both.
I have thought about:
For RECORD in $FILE
...

The first one won't work for various reasons, the main one being that "-f file" means read some awk statements to be executed from "file" - but "rent_payments" is of course the data file in this case.
The second try should have worked but only if you'd applied the patch I gave in response number 3 (there's a missing "'" on the left hand side of the original expression) and you also need to fill in the second {...} with the appropriate text and variable pattern, modelled on what is in the first {...}.
If you can't get it to work after those amendments, I'll post an explicit expression that you can cut 'n' paste.
This is the simplest way to do the job (awk is designed for precisely this sort of job) but if you want to know how to do it in a bash/ksh script later on I will be happy to oblige.

I don't understand what you mean by on the left of the original expression.
The 'patch' that you sent doesn't make sense to me and I'm quite clueless as to where to place it.
The plan was to run a script from the command line just being ./rent.

awk -F',' {print...
should read
awk -F',''{print...To explain the patch:
s/-F',' {/-F',' '{/
means search
s/-F',' {/-F',' '{/
is the string to search for
s/-F',' {/-F',' '{/
is what to replace the string with.{print "Postcode: " $2 " Name: " $1 " PAID: " $3 > "paid"} {print ... > "owed"}
should read more like:
{print "Postcode: " $2 " Name: " $1 " PAID: " $3 > "paid"} {print "Postcode: " $2 " Name: " $1 " OWED: " $4 > "owed"}

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |