Eccone uno divertente. Puoi usare sed
direttamente per eliminare tutte le copie della prima riga e lasciare tutto il resto al suo posto (inclusa la prima riga stessa).
sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input
1{h;n;}
mette la prima riga nello spazio di attesa, la stampa e legge nella riga successiva, saltando il resto dei sed
comandi per la prima riga. ( Salta1
anche quel primo test per la seconda riga , ma non importa perché quel test non si sarebbe applicato alla seconda riga.)
G
aggiunge una nuova riga seguita dal contenuto dello spazio di attesa allo spazio modello.
/^\(.*\)\n\1$/d
elimina il contenuto dello spazio del modello (saltando così alla riga successiva) se la porzione successiva alla nuova riga (ovvero ciò che è stato aggiunto dallo spazio di attesa) corrisponde esattamente alla porzione prima della nuova riga. Qui vengono eliminate le righe che duplicano l'intestazione.
s/\n.*$//
elimina la parte di testo che è stata aggiunta dal G
comando, in modo che ciò che viene stampato sia solo la riga di testo dal file.
Tuttavia, poiché regex è costoso, un approccio leggermente più veloce sarebbe quello di utilizzare la stessa condizione (negata) e P
rint fino alla nuova riga se la porzione successiva alla nuova riga (ovvero ciò che è stato aggiunto dallo spazio di attesa) non corrisponde esattamente alla porzione prima della nuova riga e quindi eliminare incondizionatamente lo spazio del modello:
sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input
L'output quando viene fornito l'input è:
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