Computing.Net > Forums > Linux > Looping through records cutting

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

Looping through records cutting

Reply to Message Icon

Name: Dan Atkinson
Date: November 4, 2004 at 08:42:51 Pacific
OS: Win 2000 / Linux
CPU/Ram: P4 1400 / 128MB
Comment:

Hi there.

I'm looking to do a basic shell script whereby there are four fields in a record:
NAME
POSTALCODE
PAID
OWED

There 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 ]
do

LINE=`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
else

NAME=`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 "" >>paid

echo -n "Postcode: $POSTCODE Name: $NAME Owed: $OWED" >>owed
echo "" >>owed

fi
done

The 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.



Sponsored Link
Ads by Google

Response Number 1
Name: Dan Atkinson
Date: November 4, 2004 at 08:51:00 Pacific
Reply:

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.


0

Response Number 2
Name: Wolfbone
Date: November 4, 2004 at 10:11:30 Pacific
Reply:

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.


0

Response Number 3
Name: Wolfbone
Date: November 4, 2004 at 10:14:07 Pacific
Reply:

s/-F',' {/-F',' '{/


0

Response Number 4
Name: 3Dave
Date: November 5, 2004 at 02:10:32 Pacific
Reply:

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";
}


0

Response Number 5
Name: Dan Atkinson
Date: November 5, 2004 at 02:52:32 Pacific
Reply:

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.


0

Related Posts

See More



Response Number 6
Name: Wolfbone
Date: November 5, 2004 at 05:21:59 Pacific
Reply:

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.


0

Response Number 7
Name: Dan Atkinson
Date: November 8, 2004 at 04:21:24 Pacific
Reply:

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
...


0

Response Number 8
Name: Wolfbone
Date: November 8, 2004 at 08:07:26 Pacific
Reply:

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.



0

Response Number 9
Name: Dan Atkinson
Date: November 8, 2004 at 08:56:03 Pacific
Reply:

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.


0

Response Number 10
Name: 3Dave
Date: November 8, 2004 at 09:20:09 Pacific
Reply:

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"}


0

Sponsored Link
Ads by Google
Reply to Message Icon






Post Locked

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


Go to Linux Forum Home


Sponsored links

Ads by Google


Results for: Looping through records cutting

useradd -p issue www.computing.net/answers/linux/useradd-p-issue/13507.html

Problem with `cut` www.computing.net/answers/linux/problem-with-cut/26742.html

parsing: perhaps sed and awk??? www.computing.net/answers/linux/parsing-perhaps-sed-and-awk/21349.html