LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   gawk scripting question (https://www.linuxquestions.org/questions/programming-9/gawk-scripting-question-917623/)

Quest ion 12-07-2011 03:53 PM

gawk scripting question
 
Hi, I was wondering per chance in anyone could lend a hand with something I am having difficulty doing,

How would I go about writting a script called "display" using gawk for data processing in the script, using a single argument such as, $./display 1998

Outputing each line in a file called cars, and add a new columb of "mileage per year". If the car is older than the specified argument mark with "*" at the beginning of the line.

An example would be,

$./display 1998
*lym fury 1970 73 2500 1.825
chevy malibu 1999 60 3000 5.455
*ford mustang 1965 45 10000 1.000
volvo s80 1998 102 9850 2.143


Any help would be apreciated, and if you just want to heckle, I implore you to at least make it funny. lol

Any help you would greatly appreciated!

Tinkster 12-07-2011 04:32 PM

More input ... which of those output columns is the "newly added"?
Are all cars identified by two words?


Cheers,
Tink

David the H. 12-07-2011 05:12 PM

Smells very much like homework to me.

If so, we'll guide you, but we won't do your work for you. So show us what you've done already, and exactly where you're having problems and we'll help you to work through them.

And please use [code][/code] tags around your code and data, to preserve formatting and to improve readability.

Quest ion 12-07-2011 06:36 PM

Quote:

Originally Posted by Tinkster (Post 4544593)
More input ... which of those output columns is the "newly added"?
Are all cars identified by two words?


Cheers,
Tink

Hi, thanks for your reply!

There is no newly added, all the cars are like that, chevy in one column, malibu in the next column et-cetera. So all the cars are identified by two words, brand and make of the car so to speak. THen the other coulumb will be the year of the car, the next column miles, etc. It's very tricky and have been wrestling with this one for awhile but to no avail as of yet unfortunately.

Quest ion 12-07-2011 06:41 PM

Quote:

Originally Posted by David the H. (Post 4544620)
Smells very much like homework to me.

If so, we'll guide you, but we won't do your work for you. So show us what you've done already, and exactly where you're having problems and we'll help you to work through them.

And please use [code][/code] tags around your code and data, to preserve formatting and to improve readability.

I'm literally stumped on this one despite putting alot of hours into trying to figue it out. If this was homework, would you think this is a fun assignment for an introductory course to linux, or just slightly over the top? If you don't know how to solve this one I wouldn't think any less of you, there are people I've asked that have been doing linux programming for a long time and they have no clue either, it's very tricky and I can't find any help in any books unfortunately. I only ask for help as a last resort, I prefer to solve problems on my own but this one literally has me stumped right now completely.

Cedrik 12-07-2011 07:21 PM

It looks like basic awk job (compare value with a field value, print...), where are you stuck ?

Quest ion 12-07-2011 07:29 PM

Quote:

Originally Posted by Cedrik (Post 4544688)
It looks like basic awk job (compare value with a field value, print...), where are you stuck ?

Really? How would you begin the solution for example? If it were basic I would have had it solved by now. lol

This is all I've been able to come up with thus far as kind of a rough sketch.


#!usr/bin/gawk -f
BEGIN{
print " Miles"
print "Make Model Year (000) Price"
print \
"----------------------------------------"
}
{
if $3 < (
if ($1 ~ /ply/) $1= "plymouth"
if ($1 ~ /chev/) $1= "chevolet"
printf "%-10s %-8s %2d %5d $ %8.2f\n,\
$1, $2, $3, $4, $5
}

Quest ion 12-07-2011 08:09 PM

Quote:

Originally Posted by Cedrik (Post 4544688)
It looks like basic awk job (compare value with a field value, print...), where are you stuck ?

So in reality you have no idea.

Would it be basic for you to hit a homerun in a major league baseball park agains professional pitching too? lol

devUnix 12-08-2011 04:30 AM

Code:

[demo@localhost bin]$ cat cars
F 1920 70 2000
M 1940 50 1000
S 1960 60 1500
V 1960 50 1000

[demo@localhost bin]$ read -p "Year? " year
Year? 1960

[demo@localhost bin]$ cat cars | awk -v YEAR=$year '{if($2 == YEAR){print $0,$4/$3}else{print "*",$0}}'
* F 1920 70 2000
* M 1940 50 1000
S 1960 60 1500 25
V 1960 50 1000 20
[demo@localhost bin]$

Modify the mileage column's value ($4/$3) above as per your requirement/mathematics. If you want mileage irrespective of a year's value matches or not, then carry that piece of code to the end of the "else" block (outside if...else, I mean.)

Note: F 1920 70 2000 = 1: "Car's Brand" 2: "Year" 3: "Km/Per Ltr" 4: "Run Total Kms"

Do you calculations there as per your requirement. But the above code answers your basic question: Asterisk-Mark Lines that do not contain a specified Year and add a Column that says blah blah!

Cedrik 12-08-2011 04:50 AM

Quote:

Originally Posted by Quest ion (Post 4544711)
So in reality you have no idea.

Would it be basic for you to hit a homerun in a major league baseball park agains professional pitching too? lol

Requirement done in one line:
Code:

awk -v y=1998 '{if($3 < y) printf "*"; print}' cars_file.txt
Look, if you don't like programming, don't waste your time, change activity...

Tinkster 12-08-2011 12:03 PM

Quote:

Originally Posted by Quest ion (Post 4544659)
Hi, thanks for your reply!

There is no newly added

Quote:

Outputing each line in a file called cars, and add a new columb of "mileage per year".
How do you make these two statements gel?



Cheers,
Tink

Quest ion 12-08-2011 07:51 PM

Hello again all, making some progress with your help but more help would be greatly appreciated!

jb_gpk 12-09-2011 03:18 AM

What is the 4th field on:
Quote:

volvo s80 1998 102 9850 2.143
why on your attempt you print only 5 fields?

I used a file named car.txt with the content:
Code:

lym fury 1970 73 2500 1.825
chevy malibu 1999 60 3000 5.455
ford mustang 1965 45 10000 1.000
volvo s80 1998 102 9850 2.143

I produced an output like this:
Code:

*lym fury        1970 (73) 2500 $1.825
chevrolet malibu        1999 (60) 3000 $5.455
*ford mustang        1965 (45) 10000 $1.000
volvo s80        1998 (102) 9850 $2.143

using the following script:

Code:

#!/usr/bin/awk -f
#filename: display.sh

BEGIN{
        ARG_YEAR = y
}
{
        CAR_YEAR = $3;
        if ( ARG_YEAR > CAR_YEAR)
                printf("*");

        #print mark
        if ( $1 ~ /chev/)
                printf("chevrolet ");
        else if  ($1 ~ /ply/)
                printf("plymouth ");
        else
                printf("%s ",$1 );

        printf("%s \t", $2);
        printf("%s ", $3);
        printf("(%s) ", $4 );
        printf("%s ",$5);
        printf("$%s \n",$6);

}

and executing it with the command:
Code:

./display.sh -v y=1979 cars.txt
where -v tells to AWK that you will pass a parameter and y is the year wich you want the older cars to be printed with *.

The entry that I used is right?

Quest ion 12-09-2011 04:50 PM

Hi, I'm trying ot make it function from a file called cars, in the file "cars" it has the following,

plym fury 1970 73 2500
chevy malibu 1999 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impala 1985 85 1550
ford explor 2003 25 9500

Quest ion 12-09-2011 05:03 PM

Quote:

Originally Posted by Cedrik (Post 4544994)
Requirement done in one line:
Code:

awk -v y=1998 '{if($3 < y) printf "*"; print}' cars_file.txt
Look, if you don't like programming, don't waste your time, change activity...

You have some skill; but I don't aspire to be a programmer, some if it is interesting but I am more into IT than CS.

I do find programming to be interesting though and I have just become intorduced ot linux programming only a couple of months ago, so though there is much I have to learn, I don't beleive even excellent programmers "knew it all" within three months. lol

Thank you for your reply though I really appreciate it, well besides the part that tried to discourage me from learning more about linux programming, because I do find some of it kind of interesting and am going ot continue to learn more on my own even after this month.

I'm going to try and tweak that code you came up with so it works for all years I type in, thanks man!!!

Tinkster 12-09-2011 05:33 PM

Quote:

Originally Posted by Quest ion (Post 4546225)
Hi, I'm trying ot make it function from a file called cars, in the file "cars" it has the following,
Code:

plym    fury    1970    73      2500
chevy  malibu  1999    60      3000
ford    mustang 1965    45      10000
volvo  s80    1998    102    9850
ford    thundbd 2003    15      10500
chevy  malibu  2000    50      3500
bmw    325i    1985    115    450
honda  accord  2001    30      6000
ford    taurus  2004    10      17000
toyota  rav4    2002    180    750
chevy  impala  1985    85      1550
ford    explor  2003    25      9500


Which brings us back to the question where the newly added 6th column
with the floating point numbers came from ... 3rd time I'm asking about
the same thing in slightly different words.
Code:

*plym  fury    1970    73      2500 1.825
chevy  malibu  1999    60      3000 5.455
*ford  mustang 1965    45    10000 1.000
volvo  s80    1998  102      9850 2.143


And please wrap your file content in code - tags to preserve spacing,
makes it much easier to read.



Cheers,
Tink

Quest ion 12-09-2011 08:31 PM

Quote:

Originally Posted by Tinkster (Post 4546244)
Which brings us back to the question where the newly added 6th column
with the floating point numbers came from ... 3rd time I'm asking about
the same thing in slightly different words.
Code:

*plym  fury    1970    73      2500 1.825
chevy  malibu  1999    60      3000 5.455
*ford  mustang 1965    45    10000 1.000
volvo  s80    1998  102      9850 2.143


And please wrap your file content in code - tags to preserve spacing,
makes it much easier to read.



Cheers,
Tink

My bad! The car file is the input file, and the script is supposed to output each line in the cars file and also add a new column of "miles per year" which is the 6th column. Then if the car is older than the specified argument, mark with a "*" at the beginning of the line.

I've spent about five hours on this today and still having no luck with that part.

Tinkster 12-10-2011 01:58 AM

Quote:

Originally Posted by Quest ion (Post 4546314)
My bad! The car file is the input file, and the script is supposed to output each line in the cars file and also add a new column of "miles per year" which is the 6th column. Then if the car is older than the specified argument, mark with a "*" at the beginning of the line.

I've spent about five hours on this today and still having no luck with that part.

I looked at the year, and the other two columns, and your "miles per year", and I can't
make those figures produce the result you computed manually in your desired output. So
which columns did you use to make the floats up?

With your input I can't make up an algorithm ....


Cheers,
Tink

Quest ion 12-10-2011 01:11 PM

Some of the numbers seem off, I'm going to double check this and then post again!

Quest ion 12-10-2011 01:54 PM

Ok, so 4th column is miles, 5th column is price and and the proposed 6th is to be calculated as miles/age of the car for miles per year.

Tinkster 12-10-2011 02:42 PM

Quote:

Originally Posted by Quest ion (Post 4546716)
Ok, so 4th column is miles, 5th column is price and and the proposed 6th is to be calculated as miles/age of the car for miles per year.

Code:

awk -v year=1999 '$3<year{printf "*"}{print $0" "$4/(strftime("%Y")-$3)}' cars
*plym    fury    1970    73      2500 1.78049
chevy  malibu  1999    60      3000 5
*ford    mustang 1965    45      10000 0.978261
*volvo  s80    1998    102      9850 7.84615
ford    thundbd 2003    15      10500 1.875
chevy  malibu  2000    50      3500 4.54545
*bmw    325i    1985    115        450 4.42308
honda  accord  2001    30      6000 3
ford    taurus  2004    10      17000 1.42857
toyota  rav4    2002    180        750 20
*chevy  impala  1985    85      1550 3.26923
ford    explor  2003    25      9500 3.125

Formatting the output to look pretty I leave as an exercise to you :o)


Cheers,
Tink

Quest ion 12-10-2011 03:20 PM

THANK YOU SO MUCH!!!!!
That was extremely helpful!!!!!

Quest ion 12-10-2011 03:32 PM

Just wanted to thank you again man!!!! Thank you to everyone else who contributed as well!

Quest ion 12-10-2011 06:35 PM

After replacing "year=1999", instead with "year=$1" it workings swimmingly!

Now to see if I can beautify the columns a bit!

Tinkster 12-10-2011 07:01 PM

Quote:

Originally Posted by Quest ion (Post 4546831)
After replacing "year=1999", instead with "year=$1" it workings swimmingly!

Now to see if I can beautify the columns a bit!

Cool. Hint: use printf and TABs (\t) ;}


Cheers,
Tink

grail 12-11-2011 09:16 PM

Well just so you can see alternatives:
Code:

awk -vy=1999 '$0 = (($3 < y)?"*":"")$0" "$4/(strftime("%Y")-$3)' cars | column -t

Quest ion 12-12-2011 07:58 PM

Awesome!!! Thanks a ton Tinkster!!!

Thank to you too grail! That's kind of interesting as well, it's kind of cool how there are multiple ways of solving the same problem with Linux! Learned something new with column -t as well! Thanks man!!


All times are GMT -5. The time now is 01:51 AM.