Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a file called students.txt and it contains the following data in the format Surname, Forename: day.month.year: Degree:

Smith, John: 15.01.1986: MSc IT 
Taylor, Susan: 04.05.1987: MSc IT 
Thomas, Steve: 19.04.1986: MSc MIT 
Sennick, Joseph: 01.12.1987: MSc IT 

I'm trying to return all lines in the format Forename,Surname: day.month.year, but without the MSc degree being studied. So far I have:

sed -e 's/\(.*\),(.*\)/\2/\1/' students.txt

What's wrong with that?

share|improve this question
2  
Is this homework? –  Mikel Mar 28 '11 at 1:57
1  
Hint: how many fields are there? You are only creating two groups/backreferences, and I think you want three. –  Mikel Mar 28 '11 at 2:00
2  
Yes, this is homework. We've seen this question at least twice before this month. –  mattdm Mar 28 '11 at 3:35
    
Do you need Forename,Surname or Forename, Surname? Is this space missing on purpose or by mistake? –  forcefsck Mar 28 '11 at 9:21
    
(Forename,Surname), there is no any space between the comma and surname. what I have written is correct. –  Host Post Mar 29 '11 at 10:35

5 Answers 5

This should do it:

sed -e 's/\([^,:]*\), *\([^:]*\)/\2, \1/;s/:[^:]*$//' student.txt

The first statement (separated by ;) searches for the Surname, delimited by comma-space, and Forename, delimited by colon, and swaps them, using a comma-space separator. The second statement searches for the last colon and removes that and anything to the end of the line. As someone mentioned this could be handled by awk.

awk -F: 'BEGIN{OFS=":"}{split($1,N,", ");$1=N[2]", "N[1];NF=2;print}' student.txt

Q.E.D

share|improve this answer
    
Thanks, your answer works great -:)) –  Host Post Mar 29 '11 at 14:39

For sed you'll want three back references. The first delimited by the comma and the second two delimited by the colon

sed 's/^\([^,]*\), \([^:]*\): \([^:]*\).*$/\2, \1: \3/' students.txt

However, when dealing with delimiter and fields, awk is really the tool to use because you can specify a field separator which can be a regex. In this case our field separator is either a comma or colon folowed by a space.

 awk -F'[,:] ' '{printf("%s, %s: %s\n",$2,$1,$3)}' students.txt
share|improve this answer
    
Thanks, your answer works great –  Host Post Mar 29 '11 at 14:38

Although, the following solution is non-generic, however if the data format remains same. Then, the following solution will work as well;

sed -r 's/^([A-Za-z]+), ([A-Za-z]+): (([0-9]{2}\.){2}[0-9]{4}): .*$/\2,\1: \3/' students.txt

Hope this helps.

share|improve this answer

Rather than sed, it might be easier use awk with a field separator of ':', and just print the first two fields.

share|improve this answer
    
OP also wants the first field modified. –  Arcege Mar 28 '11 at 2:50
2  
He asks for sed because it's homework and they are forced to do it in sed :) –  faif Mar 28 '11 at 8:01

If you don't have to use sed, use the cut command.

cut -d : -N 1-2 students.txt

would do the trick

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.