3

I have a text file with following data.

 Name             Feature
 Marry            Lecturer
 Marry            Student
 Marry            Leader
 Bob              Lecturer
 Bob              Student
 Som              Student

I have only 3 features for every person i.e. Lecturer, Student and Leader.

The example above is just a sample and in my real data I have many more Persons having these features.

Now, I want to make a Unix script by which I can check that which of the 3 features is missing for respective person.

I understand that it can be done by making key value relationship, but I'm not able to figure it out correctly.

Im running bash shell on SunOS 5.10 i386.

2
  • Hint: grep Lecturer file > lecturers, grep Student file > students and the same with Leader. Then, diff these files.
    – fedorqui
    Nov 11, 2014 at 11:12
  • Please show us what you have tried so we don't give you the same solutions.
    – terdon
    Nov 11, 2014 at 11:22

2 Answers 2

3

If you have the list of names in list.txt you can do:

for i in Student Leader Lecturer; do grep -F $i list.txt | cut -d ' ' -f 1 | sort > $i.out ; done

To get the names in 3 separate sorted files, which you can compare with diffuse (or xxdiff or diff3):

diffuse *.out

If you just want to have files with the names of the persons missing each label, you can first generate a file with all names and use uniq -u to find the ones that are not in that list (the really unique ones):

sed -n '1!p' list.txt  | cut -d ' ' -f 1 | sort -u > names.all
for i in Student Leader Lecturer; do fgrep $i list.txt | cut -d ' ' -f 1  | cat - names.all | sort | uniq -u > $i.missing ; done

If you want to do this from a script and a file feature with:

Leader 
Student
Lecturer

and the source table in example.txt, you can use:

#!/bin/bash

rm -f *.missing names.all
feature=feature
sed -n '1!p' example.txt | cut -d ' ' -f 1 | sort -u > names.all
for i in $(cat $feature)
do
    fgrep $i example.txt | cut -d ' ' -f 1 | cat - names.all | sort | uniq -u > $i.missing 
done
6
  • @user21546 I created this under bash you seem to be using ksh and you specified bash in your question.
    – Anthon
    Nov 12, 2014 at 8:26
  • if i use : #!/usr/bin/env bash instead of #!/bin/ksh , error is still there Nov 12, 2014 at 8:31
  • @user21546 Please confirm that this solution works from the bash prompt. And accept this answer if it does. Then to make this into a bash/ksh script create a new question, referring to this one, copying the (working) lines and describing what you want to do (make a script) and what errors you get. Please don't create a moving target out of this post.
    – Anthon
    Nov 12, 2014 at 8:37
  • ok i managed to fix it somehow. I can accept the answer , but im getting errors. grep -F is not working Please help me to solve it and i will accept it Nov 12, 2014 at 8:46
  • @user21546 what is the actual error that the grep line gives? And is this the line I posted, or the one from you script?
    – Anthon
    Nov 12, 2014 at 8:47
1

You can do this in pure bash using arrays:

#!/usr/bin/env bash

## Declare the various arrays we will be using
declare -A hasfeat;
declare -A names;
declare -A features;
## The input file
file="/path/to/file"

## The awk is used to skip the first line, the header
awk 'NR>1' "$file" |
    {
        while read name feat;
        do
            ## Save the names
            names[$name]=1;
            ## Save the features
            features[$feat]=1;
            ## Save this name/feature combination
            hasfeat[$name,$feat]=1;
        done
        ## For each name in the file
        for name in ${!names[@]}
        do
            ## For each feature in the file
            for feat in ${!features[@]}
            do
                ## Print the name if it doesn't have this feature
                [ -z ${array[$name,$feat]} ] && echo $name lacks $feat
            done
        done;
    }

Or, much more concisely, in Perl:

$ perl -lane 'if($.>1){$l{$F[1]}++;$k{$F[0]}{$F[1]}++}
  END{foreach $f (keys(%l)){ 
    map{print "$_ lacks $f" unless $k{$_}{$f}}keys(%k)
    }}' file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .