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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a files students.txt, with lines of the form:

Surname, Forename: Day.Month.Year: Degree

For example:

Smith, John: 15.01.1986: MSc IT
Taylor, Susan: 04.05.1987: MSc IT
Thomas, Steve: 19.04.1986: MSc MIT
Sellen, Jo: 03.07.1987: MSc CSE

How can I change the command below into a sed command to return all the surnames of students who were born in 1987?

$ grep 1987 students.txt | grep -o "^\(.*\),"
share|improve this question
You do realize this is cheating ;) There's a reason for homework assignments. – forcefsck Apr 2 '11 at 18:44
Should we merge with unix.stackexchange.com/questions/10200/… – Mikel Apr 26 '11 at 0:31
sed -n '/1987/s/^\([^,]*\),.*$/\1/p' students.txt

or as Glenn pointed out:

sed -n '/1987/s/,.*//p' students.txt
share|improve this answer
A bit simpler: s/,.*// – glenn jackman Apr 2 '11 at 17:53
thanks @glenn. You know I was looking my answer yesterday thinking there must be a faster way and then I thought about /1987/,.*/d then I realized ,no, that deletes the entire line. For some reason your answer escaped me. – SiegeX Apr 2 '11 at 18:15
Thanks SieneX... – Host Post Apr 4 '11 at 19:54

If you want to go with awk I would suggest a different answer to Johnsyweb's. The power of awk includes choosing the field separator(s):

awk -F'[,: ]*' '$3 ~ /1987$/ {print $1}' students.txt

But the question was about sed, so I believe SiegeX should get the better vote.

share|improve this answer
> It's nice that you point out that this question is notionally about sed, and probably user5836 must use sed, but one of the good things in this forum is the amount of tangential information that comes from 'related' issues... eg. mentioning the multiple field seperator (-F) is great for me, as I was wondering how to do that with awk... so you get a +1 from me :) with no demerrit implied to the sed answer.... Seeing all the alternatives is good :) – Peter.O Apr 2 '11 at 5:55
@fred: Thanks :-) – asoundmove Apr 2 '11 at 6:02

This kind of problem is well-suited to awk:

% awk '/\.1987:/ {gsub(/,.*/, ""); print}' students.txt 

Or, specifying a column, rather than the whole line (making it easier for you to customise, should you wish to add other columns in :

% awk '/\.1987:/ {
        gsub(/,$/, "", $1);          
        print $1;
}' students.txt
share|improve this answer
I like the fact you made the date more specific than just 1987; to reduce the likelyhood of clashing with 1987 appearing eslewhere in the line.... I've just started using awk, and noticed that in this case, the following will work too (in your first example).... {sub(/,.*/,"") – Peter.O Apr 2 '11 at 5:30
@fred.bear: Thank you. And thanks for pointing out that I didn't need gsub. The check for 1987 could be localised to the end of column 2, thus: awk -F':' '$2 ~ /\.1987$/ {sub(/,.*/, ""); print}' students.txt – Johnsyweb Apr 2 '11 at 5:55

Your Answer


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.