I am working on a ksh script whose scenario is as follows:

I have a text file for students' reports which contains details of students like:

Name: ABC
Head Teacher:SITA
Status: Pass 

Name: ABCE
Head Teacher:SITA
Status: Pass 

Head Teacher:RYAN
Status: Fail

Head Teacher:RYAN

What I need to do is to

  1. Find the number of students by counting the lines that start with Student_N;

  2. Count how many students passed and how many students failed using the Status: line.

  3. Find the name of students whose name starts with A.

I tried numerous things including:

sed -n '/Student_i<< Status/,/Status/p' students_details.txt >> report_card.txt
sed '/^Student_i<< Status/,/)/Status/$/!d/Status/s/^Student_i<< Status (///Status/s/);$//' students_details.txt >> report_card.txt
sed '/^Student_i<< Status/,/)Status$/!d;s/^Student_i<< Status (//;s/);$//' students_details.txt >> report_card.txt
sed '/^pass/,/);$/!d;s/^pass (//;s/);$//' students_details.txt>> report_card.txt

My desired output files are:

  • For point 1:

    Student_1 : 2
    Student_2 : 1
    Student_50: 1
  • For Point 2:

    Pass: 2
    Fail: 2
  • For Point 3:

    Count of Students whose name starts with "A" : 3
  • What is it you are looking for? You mention you want to learn. However on this site you are likely to receive pre-chewed answers that may not advance your learning that much. One tip; you seem to believe that "i" has some special meaning. In the samples posted "i" is nothing more than the letter "i". – Bram Oct 22 '15 at 7:43
  • Edited the question. Hope u will understand. At least give some pointers to resolve the issue, instead of ignoring it. – A.K. Singh Oct 22 '15 at 8:46
  • Since your data appears to consist of structured data records, I'd look at using awk or perl in 'paragraph mode' rather than sed. FWIW I don't see the relevance of the ksh tag here since you seem to be looking for a solution using external text-processing tools rather than the shell itself. – steeldriver Oct 22 '15 at 10:17
  • @steeldriver yes i am also working on different options like i had used grep -n -w filename.txt but still i am not fully satisfied. – A.K. Singh Oct 22 '15 at 10:21
  • OK so here's a freebie to get you started: awk 'BEGIN{RS=""} END{print NR}' – steeldriver Oct 22 '15 at 10:30

Personally, I would do the whole thing in Perl:

$ perl -00ne '/^(Student_\d+)/ && $count{$1}++; 
              /Name:\sA/ && $As++; 
              /Status:\s*Pass/ ? $pass++ : $fail++; 
                print "$_ : $count{$_}\n" for keys(%count); 
                print "Pass: $pass\nFail:$fail\n"; 
                print "Student names starting with A: $As\n"
            }' file 
Student_2 : 1
Student_1 : 1
Student_50 : 1
Pass: 2
Student names starting with A: 2

If you insist on separate commands per operation, you could use:

$ awk '/^Student_/{a[$0]++} END{for(s in a){print s,a[s]}}' file 
Student_1 1
Student_2 1
Student_50: 1
$ perl -ne '$pass++ if /:\s*Pass/; $fail++ if /:\s*Fail/;
     END{print "Pass: $pass\nFail: $fail\n"}' file 
Pass: 2
Fail: 2
$ echo "Student names starting with A: $(grep -c "^Name:\s*A" file )"
Student names starting with A: 2
  • Nice answer using Perl. Since the original file had white-spaces in the second block, I'd add a \s* between /^ and (Student_\d+). – Moreaki Mar 4 '19 at 23:44
  • 1
    @Moreaki good point, thanks. I'm pretty sure that was just a copy/paste error though. Note how there are other places in the file that aren't uniform (some have Name: foo and others Name:foo). I am guessing the actual file is uniform and produced by some software tool. – terdon Mar 4 '19 at 23:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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