LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   How to extract lines from file using AWK (http://www.linuxquestions.org/questions/linux-general-1/how-to-extract-lines-from-file-using-awk-824332/)

keenboy 08-05-2010 06:49 AM

How to extract lines from file using AWK
 
Hi,

I have a file similar to this:

david,1,1,1,1,50,7
david,1,1,1,1,65,8
david,1,1,1,1,89,12
thomas,1,1,1,1,40,2
bill,1,1,1,1,39,3
bill,1,1,1,1,41,4

I need to print the last line for each user into a file. The resulting file should look like this:

david,1,1,1,1,89,12
thomas,1,1,1,1,40,2
bill,1,1,1,1,41,4

Is there a way that AWK can match lines from $1 and then print the last line into a file?

Or is there a better way?

Many Thanks,

jschiwal 08-05-2010 06:52 AM

This looks like it might possibly be a homework program. Could you explain how you will use this, or show what you have tried so far. Then we will be able provide hints. If this is something you can use, you could tools such as cut, sort & tail to achieve the same thing.

keenboy 08-05-2010 07:07 AM

The file is a csv file which is exported from a website. The file contains delivery information and the last line for each name is the line that is required to print delivery labels.

The final file is imported into an application which prints the labels.

I have been able to print the required columns from an original csv file into a new file and delete repeated lines by using the uniq command. This wont work here though because the lines are all different.

I want to be able to use the awk match function to match lines based on a pattern once the lines have been matched I should be able to print the last line into a new file.

The patterns will always be different so I will have to match the lines based on the contents of column 1 being the same.

I hope this helps.

Thanks,

jschiwal 08-05-2010 07:17 AM

I'm not as handy with AWK as I am with SED.

However, tweaking what you did before should work. Use cut to obtain a list of names to match. Then use each name for grep or awk to match against.

cut -d, -f1 test | sort -u >names
for name in $(cat names); do
grep $name test | tail -1; done

keenboy 08-05-2010 07:51 AM

Thanks for that. The result isn't what was expected. I'm getting all the lines as output instead of the last line for each name.

I think I need to keep looking at AWK functions, match in particular.

druuna 08-05-2010 07:53 AM

Hi,

Is this what you are looking for:
Code:

#!/bin/bash

sort infile | \
awk 'BEGIN { FS = "," ; prevUser = "" }
{ if ( prevUser != $1 ) {
      print $0
  }
  prevUser = $1
}
'

Example run:
Code:

$ cat infile
david,1,1,1,1,50,7
bill,1,1,1,1,39,3
david,1,1,1,1,89,12
thomas,1,1,1,1,40,2
david,1,1,1,1,65,8
bill,1,1,1,1,41,4

$ ./one.only.sh
bill,1,1,1,1,39,3
david,1,1,1,1,50,7
thomas,1,1,1,1,40,2

Hope this helps.

ghostdog74 08-05-2010 08:19 AM

No order though
Code:

awk -F"," '{a[$1]=$0}END{for(i in a) print i,a[i]}' file

keenboy 08-05-2010 09:29 AM

Thank you both. They work well. ghostdog74 perfect order, thank you again.


All times are GMT -5. The time now is 11:46 PM.