En voici une amusante. Vous pouvez utiliser sed
directement pour supprimer toutes les copies de la première ligne et laisser tout le reste en place (y compris la première ligne elle-même).
sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input
1{h;n;}
place la première ligne dans l'espace d'attente, l'imprime et lit à la ligne suivante, en ignorant le reste des sed
commandes de la première ligne. (Il ignore1
également ce premier test pour la deuxième ligne , mais cela n'a pas d'importance car ce test n'aurait pas été appliqué à la deuxième ligne.)
G
ajoute une nouvelle ligne suivie du contenu de l'espace d'attente à l'espace de motif.
/^\(.*\)\n\1$/d
supprime le contenu de l'espace de motif (sautant ainsi à la ligne suivante) si la partie après la nouvelle ligne (c'est-à-dire ce qui a été ajouté de l'espace d'attente) correspond exactement à la partie avant la nouvelle ligne. C'est là que les lignes qui dupliquent l'en-tête seront supprimées.
s/\n.*$//
supprime la partie de texte qui a été ajoutée par la G
commande, de sorte que ce qui est imprimé n'est que la ligne de texte du fichier.
Cependant, étant donné que l'expression régulière coûte cher, une approche légèrement plus rapide consisterait à utiliser la même condition (niée) et à P
imprimer jusqu'à la nouvelle ligne si la partie après la nouvelle ligne (c'est-à-dire ce qui a été ajouté à partir de l'espace d'attente) ne correspond pas exactement à la partie. avant la nouvelle ligne, puis supprimez inconditionnellement l'espace de motif:
sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input
La sortie lorsque votre entrée est donnée est:
ID Data1 Data2
1 100 100
2 100 200
3 200 100
4 100 100
5 200 200
{ IFS= read -r head; printf '%s\n' "$head"; grep -vF "$head" ; } <file