Encontrando valor ausente no arquivo de texto

3

Eu tenho um arquivo de texto com os seguintes dados.

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

Eu tenho apenas três recursos para cada pessoa, por exemplo, Docente , Estudante e Líder .

O exemplo acima é apenas uma amostra e, em meus dados reais, tenho muito mais Pessoas com esses recursos.

Agora, quero criar um script Unix pelo qual possa verificar qual dos três recursos está faltando para a respectiva pessoa.

Eu entendo que isso pode ser feito estabelecendo um relacionamento de valor-chave, mas não sou capaz de descobrir isso corretamente.

Estou executando bash shell no SunOS 5.10 i386.

    
por user21546 11.11.2014 / 12:09

2 respostas

3

Se você tem a lista de nomes em list.txt, você pode fazer:

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

Para obter os nomes em três arquivos separados, que você pode comparar com diffuse (ou xxdiff ou diff3 ):

diffuse *.out

Se você quiser apenas ter arquivos com os nomes das pessoas que faltam em cada etiqueta, primeiro você pode gerar um arquivo com todos os nomes e usar uniq -u para encontrar os que não estão nessa lista (os realmente únicos) :

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

Se você quiser fazer isso de um script e um arquivo feature com:

Leader 
Student
Lecturer

e a tabela de origem em example.txt , você pode usar:

#!/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
    
por 11.11.2014 / 12:28
1

Você pode fazer isso em puro bash usando matrizes:

#!/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;
    }

Ou, muito mais concisamente, em 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
    
por 11.11.2014 / 13:25