En voici une amusante. Vous pouvez utiliser seddirectement 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 sedcommandes 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$/dsupprime 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 Gcommande, 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 à Pimprimer 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